在SQL Server中,使用WHERE子句的IN子句无法得到正确的结果。

7 浏览
0 Comments

在SQL Server中,使用WHERE子句的IN子句无法得到正确的结果。

存储过程中的一段代码。如果我执行这段代码,即使它有一些要返回的行,也不会返回任何行。问题出在IN子句上,如果我没有向IN子句传递任何内容,即@InvoiceMethod为空,那么我会得到行。

如果我向@InvoiceMethod传递任何内容,我就不会得到任何行。

@InvoiceMethod的值为'A','B'

我尝试了许多组合,如'A','B'"A","B",但没有任何结果。

请问如何传递给IN子句的值?以哪种格式?

请帮我解决这个问题。

将存储过程修改为以下内容:

DECLARE @tmpt TABLE (value NVARCHAR(5) NOT NULL)
SET @InvoiceCount = (SELECT COUNT(*) FROM dbo.fnSplit(@InvoiceMethod, ','))
SET @tempVar = 1;
WHILE @tempVar <= (@InvoiceCount)
BEGIN
    INSERT INTO @tmpt (value) 
    VALUES (@InvoiceMethod);//这里我需要将一系列的值插入到临时表中,例如根据@InvoiceCount插入invoicemethod[0]、invoicemethod[1]和invoicemethod[2]
    SET @tempVar = @tempVar + 1;
END
SELECT Col1,Col2,Col3,Col4
FROM Table1 
WHERE User1 = @Owner
    AND group1 = @Group
    AND date1 BETWEEN @startDate AND @endDate
    AND Mail LIKE @email
    AND def IN (SELECT value FROM @tmpt)

但是没有得到预期的结果 🙁

0
0 Comments

在SQL Server中,使用WHERE子句和IN子句时,没有得到正确的结果。这个问题的出现是因为将列的过滤值作为逗号分隔的字符串传递,这几乎鼓励了动态SQL方法(即使用EXEC执行构建的SQL字符串并将其作为字符串粘贴)。相反,SQL Server 2008提供了“表值参数”(Table Valued Parameters)的功能,(在此之前,可以使用XML进行处理),它允许您以表格形式将结构化数据传递给存储过程。然后,您只需要将表值参数与表格进行连接,以实现1..N值的IN过滤。

创建一个表值参数类型ttInvoiceMethods,然后创建一个存储过程dbo.SomeProc,该存储过程接受ttInvoiceMethods作为只读的表值参数,然后在查询中将其与相应的列进行连接,并通过JOIN来进行过滤。

有一个类似的解决方案,请参考链接:https://stackoverflow.com/a/23284745/314291。

如果要处理可选参数(=''),可以通过将JOIN更改为带有子查询的表值参数来解决:

WHERE

-- ... 其他过滤条件

AND (Table1.def IN (SELECT Method FROM ))

OR IS NULL)

要将表值参数初始化为NULL,只需在C#中不绑定该参数即可。

实际上,是动态的,例如:Select * from table1 where col1 IN('India','US','Singapore')。但是col1中有10个国家名称,我只需要IN子句中提到的国家名称。

在应用程序中,我有一个复选框列表,其中有10个项目,用户根据自己的选择进行选择。无论用户选择什么,我都将其传递给存储过程的IN子句。

是的,我们明白了,并且根据您的问题描述,如果用户没有选择任何内容,似乎意味着要完全忽略该过滤器(即使用所有可能的值)。作为一个临时解决方案,可以考虑e4rthdog的建议(将值解包到一个表变量中并与之连接)。但作为一种更有效的模式,请从一开始就考虑传递结构化数据,例如表值参数。

谢谢Stuart,我对表值参数还不熟悉,所以感到困惑。让我试试你提出的解决方案。

在这种情况下,我建议您首先尝试e4rthdog的方法,因为它解决了问题的核心,并且不需要更改存储过程和C#代码。Table Valued Parameters将需要更改C#代码,因为您需要填充一个DataTable或其他结构。

0
0 Comments

在SQL Server中,有时候使用带有WHERE子句的IN子句时可能会导致结果不正确。下面将介绍导致这个问题出现的原因以及解决方法。

在上面的代码中,我们可以看到在IN子句中使用了一个子查询(SELECT * FROM sptFunction(,','))来返回一个值列表。这个子查询使用了一个名为sptFunction的函数来将一个字符串分割成多个值,这些值将被用于IN子句中。

然而,问题出现在这里。在SQL Server中,IN子句只能接受一个列或一个子查询,它不能直接接受一个值列表。因此,当我们在IN子句中使用一个子查询返回一个值列表时,SQL Server会将整个值列表作为一个单独的值来处理,而不是将它们作为多个值进行比较。

为了解决这个问题,我们可以使用一种称为Splitfunctions的方法。Splitfunctions是一个自定义的函数,它接受一个字符串和一个分隔符作为参数,并将字符串分割成多个值。

在上面的代码中,我们将IN子句修改为使用Splitfunctions函数来分割字符串并返回多个值。通过这样做,我们可以确保IN子句中的每个值都会被视为一个独立的值进行比较,而不是将整个值列表作为一个单独的值进行比较。

经过修改后的代码如下所示:

SELECT Col1, Col2, Col3, Col4
FROM Table1 
WHERE User1 = 
AND group1 = 
AND date1 BETWEEN  AND 
AND Mail LIKE 
AND def IN (SELECT * FROM sptFunction(,','))

通过使用Splitfunctions函数,我们可以确保IN子句中的每个值都会被视为一个独立的值进行比较,从而解决了IN子句与WHERE子句一起使用时可能出现的结果不正确的问题。

0
0 Comments

在SQL Server中,使用IN子句和WHERE子句时无法获得正确的结果。

问题的原因是IN子句不允许使用逗号分隔的多个值的变量。你应该使用字符串函数(split和join)或者使用临时表的解决方案。我更喜欢使用第二种方法。

解决方法是使用临时表来存储你的值,然后将其传递给IN语句。

DECLARE @tmpTable TABLE (value NVARCHAR(5) NOT NULL)
INSERT INTO @tmpTable
...
...
SELECT Col1,Col2,Col3,Col4
FROM Table1
WHERE User1 = 
    AND group1 = 
    AND date1 BETWEEN  AND 
    AND Mail LIKE 
    AND def IN (SELECT value FROM @tmpTable)

我根据你的解决方案修改了存储过程,但是得不到结果。请查看修改后的问题。

你能提供一个在tmp表中的select输出吗?Invoicemethod不应该像'cc','yy','zz'那样,你应该逐个将值插入到tmp表中,'cc','yy','zz'..你必须对每个不同的invoicemethod值进行迭代..请告诉我们你是如何计算的?

由于我对临时表还不熟悉,请提供一些关于如何向临时表中插入数据/多条记录的链接或示例。这对我非常有帮助。我在网络上搜索了一下,但是没有找到合适的信息。

我修改了问题。我无法将多个记录插入到临时表中。

0