Tsql 尝试运行SQL查询时出错,其中一个变量的值以逗号作为字符串

Tsql 尝试运行SQL查询时出错,其中一个变量的值以逗号作为字符串,tsql,sql-server-2014,Tsql,Sql Server 2014,我在下面的sql查询中得到了错误。对于osdsId变量,我将从UI以列表形式获取值。这就是我为测试硬编码值的原因。但它将错误显示为“子查询返回的值超过1”。当子查询在=、!=、=或者当子查询用作表达式时。但是,如果我只指定一个值,它就会工作。多谢各位 declare @osdsId VARCHAR(max) = '4292, 4293', @pqrId VARCHAR(max) = NULL, @queryOrderBy VARCHAR(max) = 'DATE_INSERTED ASC'

我在下面的sql查询中得到了错误。对于osdsId变量,我将从UI以列表形式获取值。这就是我为测试硬编码值的原因。但它将错误显示为“子查询返回的值超过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      

我相信这是因为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   

我之所以使用COALESCE,是因为有一个条件,如果pass参数有值,则只应用该条件,否则返回与该列@colinGYou相关的所有内容,实际上不需要对COALESCE执行任何操作。您可以只测试参数是否为NULL。我编辑了我的代码以包含它。您还可以添加一个变量来获取UDF返回的表的计数,并对其进行测试,以确定是否应该使用该条件。