尝试 运行 SQL 查询时出错,其中一个变量的值以逗号作为字符串
Error while trying to run SQL queries with one variable having values with comma as a string
我在以下 sql 查询中收到错误。对于 osdsId 变量,我将从 UI 中获取值作为列表。这就是我硬编码测试值的原因。但是它显示错误为 'Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.' 但是,如果我只分配一个值,它就可以工作。谢谢你。
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 正在 returning a table,但 COALESCE 期望其参数是单个值。因此,当 return 从 table 编辑两个值时,这就是错误的来源。您可以添加 TOP 1,但这会破坏目的。
我会做什么:在您的查询之外声明一个 table 变量和 运行 UDF。 运行 无论如何在子查询中都是低效的,因为它在整个执行过程中是一致的。
虽然我不清楚您为什么要使用 COALESCE。那是因为如果解析函数失败并且 return 为 NULL,您仍然希望它成为 return 某些东西吗?因为在那种情况下它会 return 一切。
因此,假设您的 FN_PARSETEXT2TABLE_TEXTONLY return 是一个具有单个整数列的 table:
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
我在以下 sql 查询中收到错误。对于 osdsId 变量,我将从 UI 中获取值作为列表。这就是我硬编码测试值的原因。但是它显示错误为 'Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.' 但是,如果我只分配一个值,它就可以工作。谢谢你。
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 正在 returning a table,但 COALESCE 期望其参数是单个值。因此,当 return 从 table 编辑两个值时,这就是错误的来源。您可以添加 TOP 1,但这会破坏目的。
我会做什么:在您的查询之外声明一个 table 变量和 运行 UDF。 运行 无论如何在子查询中都是低效的,因为它在整个执行过程中是一致的。
虽然我不清楚您为什么要使用 COALESCE。那是因为如果解析函数失败并且 return 为 NULL,您仍然希望它成为 return 某些东西吗?因为在那种情况下它会 return 一切。
因此,假设您的 FN_PARSETEXT2TABLE_TEXTONLY return 是一个具有单个整数列的 table:
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