2009-05-17 97 views
1

我有一个字符串,它是一个函数的输出,例如:“1,3,16,..,..”。SQL中的Charindex没有给出想要的结果

我使用了以下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查询不给我任何结果?

我似乎无法弄清楚这个问题,请帮助。

回答

1

CHARINDEX只是返回在字符串中找到字符的位置。当@ItemIDs设置为'3,16'那么你WHERE条款等

WHERE (ItemID = CAST(CHARINDEX(',', @ItemIDs) AS INT)) 

所以......就等于......

WHERE ItemID = 2 

...因为自CHARINDEX回报2逗号字符位于字符串'3,16'的位置2处。

我猜(一)你没有行的表,其中ItemID2(B)你真的不希望逗号的位置,以决定哪些行返回。

+0

(一)我没有记录下条目标识为2 (B)我想查询以获得我的记录。 注意:@ItemIDs可以包含不同的值,而不是每次“3,16”。 我该如何做到这一点? 谢谢 – pier 2009-05-17 23:59:35

0

尝试 SELECT项ID,姓名,RelDate,价钱,状态从item_k WHERE项目ID在(@itemIDs)

+0

嗯。如果我给出1的值作为参数,这将工作。当我输入“3,12”作为参数时,给出类型不匹配。 – pier 2009-05-18 00:33:19

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命令在变量中执行查询。

+0

Coudl you pls。解释在这个查询中究竟发生了什么? – pier 2009-05-18 08:19:10

3

这是另一个解决方案。根据我的经验,当你有一个ItemIds列表作为逗号分隔的字符串时,你需要一个分割函数。这非常有用。

有分流的功能,你可以简单地做一个INNER与呼叫分割功能并通过ItemIds列表的结果和相关定界符JOIN如下:

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 

虽然这可能起初看上去很复杂,这是更优雅和可维护的解决方案。以下是创建功能的代码。你需要运行这个第一:

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 
相关问题