Ошибка при попытке запуска SQL-запросов с одной переменной, значения которой запятая в виде строки - PullRequest
0 голосов
/ 26 сентября 2018

Я получаю сообщение об ошибке в следующих SQL-запросах.Для переменной osdsId я получу значения в виде списка из пользовательского интерфейса.Вот почему я жестко закодировал значение для тестирования.Но он отображает ошибку, поскольку 'Подзапрос возвратил больше чем 1 значение.Это недопустимо, если подзапрос следует =,! =, <, <=,>,> = Или когда подзапрос используется в качестве выражения. 'Тем не менее, это работает, если я просто назначить только одно значение.Спасибо.

 declare @osdsId VARCHAR(max) = '4292, 4293',
 @pqrId VARCHAR(max) = NULL,
 @queryOrderBy VARCHAR(max) = 'DATE_INSERTED ASC',
 @rowLimit   INT = 0,
 @startRow   INT = 0,
 @endRow     INT = 0

SELECT * FROM (
        SELECT
            ROW_NUMBER() OVER (ORDER BY @queryOrderBy ) AS ROWNUM,
            S.OSDS_ID, 
            S.PQR_ID, 
            S.DATE_INSERTED, 
            S.BUY_CURRENCY, 
            S.SELL_CURRENCY, 
            S.BUY_EXCHANGE_RATE, 
            S.SELL_EXCHANGE_RATE, 
            S.BUY_PERCENT, 
            S.SELL_PERCENT
        FROM
            table1 S
        WHERE
            1=1
            AND S.OSDS_ID IN (COALESCE((SELECT TXT_VALUE FROM 
DBO.FN_PARSETEXT2TABLE_TEXTONLY(@osdsId, ',') ), S.OSDS_ID)) 
            AND S.PQR_ID IN (COALESCE((SELECT TXT_VALUE FROM 
DBO.FN_PARSETEXT2TABLE_TEXTONLY(@pqrId, ',') ), S.PQR_ID)) 
        )x
        WHERE ROWNUM BETWEEN  
        CASE WHEN (@rowLimit > 0) THEN @startRow ELSE ROWNUM END
        AND CASE WHEN (@rowLimit > 0) THEN @endRow ELSE ROWNUM END      

1 Ответ

0 голосов
/ 26 сентября 2018

Я полагаю, это потому, что ваш FN_PARSETEXT2TABLE_TEXTONLY возвращает таблицу, но COALESCE ожидает, что его аргументы будут одним значением.Таким образом, когда из таблицы возвращаются два значения, возникает ошибка.Вы могли бы добавить TOP 1, но это не помогло бы.

Что бы я сделал: объявить переменную таблицы и запустить UDF для нее вне вашего запроса.В любом случае неэффективно выполнять это в подзапросе, поскольку он непротиворечив во время выполнения.

Я не совсем понимаю, почему вы используете COALESCE.Это потому, что если функция синтаксического анализа завершается неудачно и возвращает NULL, вы все равно хотите, чтобы она что-то возвращала?Потому что в этом случае все будет возвращено.

Итак, при условии, что ваш FN_PARSETEXT2TABLE_TEXTONLY возвращает таблицу с одним целочисленным столбцом:

 declare @osdsId VARCHAR(max) = '4292, 4293',
 @pqrId VARCHAR(max) = NULL,
 @queryOrderBy VARCHAR(max) = 'DATE_INSERTED ASC',
 @rowLimit   INT = 0,
 @startRow   INT = 0,
 @endRow     INT = 0,
 @osdsTbl TABLE (oid INT),
 @pqrTbl TABLE (pid INT);

SET @osdsTbl = DBO.FN_PARSETEXT2TABLE_TEXTONLY(@osdsId, ',');
SET @pqrTbl = DBO.FN_PARSETEXT2TABLE_TEXTONLY(@pqrId, ',');

SELECT * FROM (
        SELECT
            ROW_NUMBER() OVER (ORDER BY @queryOrderBy ) AS ROWNUM,
            S.OSDS_ID, 
            S.PQR_ID, 
            S.DATE_INSERTED, 
            S.BUY_CURRENCY, 
            S.SELL_CURRENCY, 
            S.BUY_EXCHANGE_RATE, 
            S.SELL_EXCHANGE_RATE, 
            S.BUY_PERCENT, 
            S.SELL_PERCENT
        FROM
            table1 S
        WHERE
            1=1
            AND (@osdsId IS NULL OR (@osdsId IS NOT NULL AND S.OSDS_ID IN (SELECT * FROM @osdsTbl))
            AND (@pqrId IS NULL OR (@pqrId IS NOT NULL AND S.PQR_ID IN (SELECT * FROM @pqrTbl))
        )x
        WHERE ROWNUM BETWEEN  
        CASE WHEN (@rowLimit > 0) THEN @startRow ELSE ROWNUM END
        AND CASE WHEN (@rowLimit > 0) THEN @endRow ELSE ROWNUM END   
...