我有一个字符串,它是函数的输出,例如:“1,3,16,..,..”。
我使用了以下SQL查询并在Visual Studio的查询构建器中运行它,它没有给我任何语法错误。
SELECT ItemID, Name, RelDate, Price, Status FROM item_k WHERE (ItemID = cast(charindex(',', @itemIDs) as int))
我给了3,16作为@itemID参数值,但它没有给出所需的结果。
然后我使用了以下SQL查询(没有charindex):
SELECT ItemID, Name, RelDate, Price, Status FROM item_k WHERE (ItemID = @itemIDs)
我给了3作为@itemID参数值,我得到了一个结果。 我还给了16个(在另一个场合)作为@itemID参数值,我得到了一个结果。我得出结论,ItemID 3和& 16。
为什么带有charindex的SQL查询不能给我任何结果?
我似乎无法在这里找出问题,请帮忙。
答案 0 :(得分:3)
这是另一种解决方案。根据我的经验,当您将ItemId列表作为逗号分隔值的字符串时,您需要一个split函数。这非常有用。
使用split函数,您可以简单地使用调用split函数的结果进行INNER JOIN,并传递ItemIds和相关分隔符的列表,如下所示:
DECLARE @ItemIDs varchar(100)
SET @ItemIDs = '1,3,16,22,34,35'
SELECT
ItemID, Name, RelDate, Price, Status
FROM item_k
INNER JOIN dbo.UTILfn_Split(@ItemIDs,',') itemIds
ON itemIds.Value = item_k.ItemID
虽然这可能看起来很复杂,但它是更优雅和可维护的解决方案。以下是用于创建 dbo.UTILfn_Split 功能的代码。你需要先运行它:
IF EXISTS (SELECT * FROM sysobjects WHERE id =
object_id(N'[dbo].[UTILfn_Split]') AND xtype IN (N'FN', N'IF', N'TF'))
DROP FUNCTION [dbo].[UTILfn_Split]
GO
CREATE FUNCTION dbo.UTILfn_Split
(
@String nvarchar (4000),
@Delimiter nvarchar (10)
)
RETURNS @ValueTable TABLE ([Value] nvarchar(4000))
BEGIN
DECLARE @NextString nvarchar(4000)
DECLARE @Pos int
DECLARE @NextPos int
DECLARE @CommaCheck nvarchar(1)
--Initialize
SET @NextString = ''
SET @CommaCheck = RIGHT(@String,1)
--Check for trailing Comma, if not exists, INSERT
--if (@CommaCheck <> @Delimiter )
SET @String = @String + @Delimiter
--Get position of first Comma
SET @Pos = CHARINDEX(@Delimiter,@String)
SET @NextPos = 1
--Loop while there is still a comma in the String of levels
WHILE (@pos <> 0)
BEGIN
SET @NextString = SUBSTRING(@String,1,@Pos - 1)
INSERT INTO @ValueTable ( [Value]) Values (@NextString)
SET @String = SUBSTRING(@String,@pos +1,LEN(@String))
SET @NextPos = @Pos
SET @pos = CHARINDEX(@Delimiter,@String)
END
RETURN
END
答案 1 :(得分:1)
CHARINDEX
只返回在字符串中找到字符的帖子。
因此,当@ItemIDs
设置为'3,16'
时,您的WHERE
条款......
WHERE (ItemID = CAST(CHARINDEX(',', @ItemIDs) AS INT))
......等同于......
WHERE ItemID = 2
...因为CHARINDEX
返回2
,因为逗号字符位于字符串'3,16'
的第2位。
我猜是(a)您的表格中没有ItemID
为2
的行,而(b)你真的不希望逗号的位置决定返回哪些行。
答案 2 :(得分:1)
您可以使用in
运算符动态创建查询:
declare @Sql varchar(1000)
set @Sql = 'select ItemID, Name, RelDate, Price, Status from item_k where ItemID in (' + @itemIDs + ')'
exec(@Sql)
但要小心你发送到程序中的内容。与任何动态SQL一样,如果数据来自用户输入而未经验证,则该过程对SQL注入是开放的。
编辑:
这就是查询中发生的情况:
首先,我们声明一个变量来保存动态查询。这只是一个足够大的varchar
变量。
在变量中,我们将@itemIDs变量放在两个字符串之间以形成查询。逗号分隔值放在in
运算符的括号之间,以形成类似于:where ItemID in (1,3,16)
的表达式
最后,exec
命令在变量中执行查询。
答案 3 :(得分:0)
尝试 SELECT ItemID,Name,RelDate,Price,Status FROM item_k WHERE ItemID in(@itemIDs)