因为IN子句()SQL Server不是这样工作的

因为IN子句()SQL Server不是这样工作的,sql,sql-server,Sql,Sql Server,看看有没有人能回答我这个问题: 这是我的SQL查询,它加载到一个临时表中,以便查询Posteriormente。所有这些都进行得很顺利: DECLARE @listStr VARCHAR(MAX) SELECT @listStr = COALESCE(@listStr+' ,' , '') + sCodProducto FROM dbo.Productos WHERE sCodProducto IN (80063, 80061, 80067, 80062, 80065) INSERT INT

看看有没有人能回答我这个问题: 这是我的SQL查询,它加载到一个临时表中,以便查询Posteriormente。所有这些都进行得很顺利:

DECLARE @listStr VARCHAR(MAX)
SELECT @listStr = COALESCE(@listStr+' ,' , '') + sCodProducto 
FROM dbo.Productos WHERE sCodProducto IN (80063, 80061, 80067, 80062, 80065)

INSERT INTO #IDPROD2(CODIGO) 
SELECT @listStr
如果我选择此选项,将显示以下数据:

SELECT * FROM #IDPROD2
SELECT * FROM dbo.Productos P WHERE P.sCodProducto IN (SELECT CODIGO FROM #IDPROD2)
SELECT * FROM dbo.Productos P WHERE P.sCodProducto IN (80061 ,80062 ,80063 ,80065 ,80067)

好吧,现在如果我咨询,那么这不会给我带来什么:

SELECT * FROM #IDPROD2
SELECT * FROM dbo.Productos P WHERE P.sCodProducto IN (SELECT CODIGO FROM #IDPROD2)
SELECT * FROM dbo.Productos P WHERE P.sCodProducto IN (80061 ,80062 ,80063 ,80065 ,80067)
现在,如果它是这样工作的:

SELECT * FROM #IDPROD2
SELECT * FROM dbo.Productos P WHERE P.sCodProducto IN (SELECT CODIGO FROM #IDPROD2)
SELECT * FROM dbo.Productos P WHERE P.sCodProducto IN (80061 ,80062 ,80063 ,80065 ,80067)

查询结果中的字段被视为单个值。该字段的实际内容无关紧要。不管您是否有CSV格式的数字,或者只有一个数字——就DB而言,整个数据块都是一个值

由于它是单个值,因此
codigo
字段的内容被解析/执行为:

... WHERE foo IN (@codigo)
... WHERE foo IN ('1,2,3,4,...');
... WHERE foo = '1,2,3,4,....';
DB将NOT解析这些值,因此将NOT将字符串视为多个不同的值

如果希望将单个字段或变量的内容视为多个不同的值,则必须使用动态sql:

sql = "SELECT .... WHERE foo IN (" + @codigo + ")";
exec @sql;
请注意,这基本上是SQL注入的一种形式。从该变量字段中删除单个值的“上下文”,并强制DB将其视为多个不同的值

一些数据库通过提供提取功能来解决这一问题,例如mysql的
find_in_set
,专门为此设计:

SELECT ... WHERE FIND_IN_SET('80063', '80063, 80061, 80067, 80062, 80065');
TSQL中没有这样的函数,但是可以模拟,即使是像这样的简单查询:

... WHERE foo='80063' OR foo LIKE '80063,%' OR foo LIKE '%,80063,%' OR foo LIKE '%,80063'

查询结果中的字段被视为单个值。该字段的实际内容无关紧要。不管您是否有CSV格式的数字,或者只有一个数字——就DB而言,整个数据块都是一个值

由于它是单个值,因此
codigo
字段的内容被解析/执行为:

... WHERE foo IN (@codigo)
... WHERE foo IN ('1,2,3,4,...');
... WHERE foo = '1,2,3,4,....';
DB将NOT解析这些值,因此将NOT将字符串视为多个不同的值

如果希望将单个字段或变量的内容视为多个不同的值,则必须使用动态sql:

sql = "SELECT .... WHERE foo IN (" + @codigo + ")";
exec @sql;
请注意,这基本上是SQL注入的一种形式。从该变量字段中删除单个值的“上下文”,并强制DB将其视为多个不同的值

一些数据库通过提供提取功能来解决这一问题,例如mysql的
find_in_set
,专门为此设计:

SELECT ... WHERE FIND_IN_SET('80063', '80063, 80061, 80067, 80062, 80065');
TSQL中没有这样的函数,但是可以模拟,即使是像这样的简单查询:

... WHERE foo='80063' OR foo LIKE '80063,%' OR foo LIKE '%,80063,%' OR foo LIKE '%,80063'

使用表值参数并对其进行内部联接。因为字符串标量变量是单个值。它不会被解释为代码或列表。这是(1,2,3)中的
和('1,2,3')中的
之间的区别。
你@matbaile如何转换这个:'800618006280063800658006780075',在这里:'80061','80062','80063','80065','80067','80075'使用一个表值参数并内部连接到它。因为字符串标量变量是单个值。它不会被解释为代码或列表。这是(1,2,3)
中的
和('1,2,3')中的
之间的区别。
你@Matbaile怎么能转换这个:'800618006280063800658006780075'在这个:'80061','80062','80063','80065','80067','80075'
','++@list+','LIKE'','+field+',%'
怎么能转换这个:'80061800628006280063800658006780075'在这个:'80061',',‘80062’、‘80063’、‘80065’、‘80067’、‘80075’它们是整数。它们不需要被引用。去掉前导/尾随引号。
,“++@list+”,“LIKE%”,“+field+”,“%”
如何转换这个:'800618006280063800658006780075',在这里:'80061','80062','80063','80065','80067','80075'它们是整数。它们不需要被引用。只需去掉前导/尾随引号。