动态SQL逗号分隔值查询

时间:2009-02-05 17:54:16

标签: sql dynamic-sql delimiter delimited

[更新:使用SQL Server 2005]

嗨,我想要做的是使用逗号分隔的值列表(ids)查询我的存储过程以检索数据行。

我收到的问题是转换错误:

Conversion failed when converting the varchar value ' +
@PassedInIDs + ' to data type int.

我的where子句和错误中的语句是:

...
AND (database.ID IN (' + @PassedInIDs + '))

注意:database.ID属于int类型。

我正在关注这篇文章:

http://www.sql-server-helper.com/functions/comma-delimited-to-table.aspx

但由于错误而没有完成。

在我的执行脚本中,我有:

...
@PassedInIDs= '1,5'

我在这里做错了吗? 谢谢你的帮助。

9 个答案:

答案 0 :(得分:1)

我强烈建议您使用该链接中的第二种方法。创建一个用户定义的函数,将逗号分隔的字符串转换为表格,然后您可以轻松地从中进行选择。

如果您在Erland和“动态SQL”上使用谷歌,他会很好地了解它所带来的陷阱。

答案 1 :(得分:1)

首先,您将字符串传递给SQL中的IN函数。如果你回顾一下原始文章,你会看到它不是发出直接的SQL语句,而是构建一个string,它是要执行的SQL语句。

答案 2 :(得分:1)

我会创建一个CLR表值函数:

http://msdn.microsoft.com/en-us/library/ms131103.aspx

在其中,您将分离字符串并执行到一组行的转换。然后,您可以加入该表的结果,或使用IN查看列表中是否有ID。

答案 3 :(得分:0)

您需要将ufn_CSVToTable视为表格。所以你可以加入这个功能:

JOIN ufn_CSVToTable(@PassedInIDs) uf ON database.ID = uf.[String]

答案 4 :(得分:0)

我建议在SQL 2005中使用XML。这有点笨重,但它可以更容易。它允许您将XML选择到一个表中,然后可以将其连接或插入等。

如果你还没有,请查看Sql Server的OPENXML()。

例如,您可以传递以下内容: '12 ...'

然后使用:

exec sp_xml_preparedocument @doc OUTPUT, @xmlParam

SELECT element 
FROM OPENXML (@doc, 'Array/Value', 2) WITH (element varchar(max) 'text()')

这应该是一个开始

答案 5 :(得分:0)

SQL中没有字符串评估。这样:

database.ID IN (' + @PassedInIDs + ')

不会转向:

database.ID IN (1,2,3)

只是因为@PassedInIDs参数恰好包含'1,2,3'。甚至没有查看该参数,因为您拥有的只是包含" + @PassedInIDs + "字符串。从语法上讲,这相当于:

database.ID IN ('Bob')

要缩短它,你不能在SQL中做你在这里尝试的东西。但还有其他四种可能性:

  1. 您使用调用语言构造SQL字符串并完全放弃存储过程
  2. 在平移使用
  3. 时,您在IN子句中使用带有尽可能多参数的动态预准备语句
  4. 你使用一个固定的预备语句,例如10个参数:IN (?,?,?,?,?,?,?,?,?,?),只填充你需要的数量,将其他参数设置为NULL
  5. 您创建一个存储过程,例如10个参数,并根据需要传入,将其他参数设置为NULL:IN (@p1, @p2, ..., @p10)

答案 6 :(得分:0)

这可以通过Narayana的文章Passing a list/array to an SQL Server stored procedure

中提到的6种方式来解决

我最直接的实施是

  

声明 @statement nvarchar (256)
  设置 @statement ='选择*来自Persons.id in('+ @PassedInIDs +')'的人    exec sp_executesql @statement

    -

答案 7 :(得分:0)

以下是我发现和测试的内容:

SET QUOTED_IDENTIFIER ON
SET ANSI_NULLS ON
GO
CREATE  FUNCTION [dbo].[SplitStrings] ( @IDsList VARCHAR(MAX) )
RETURNS @IDsTable TABLE ( [ID] VARCHAR(MAX) )
AS 
BEGIN
    DECLARE @ID VARCHAR(MAX)
    DECLARE @Pos VARCHAR(MAX)

    SET @IDsList = LTRIM(RTRIM(@IDsList)) + ','
    SET @Pos = CHARINDEX(',', @IDsList, 1)

    IF REPLACE(@IDsList, ',', '') <> '' 
        BEGIN
            WHILE @Pos > 0 
                BEGIN
                    SET @ID = LTRIM(RTRIM(LEFT(@IDsList, @Pos - 1)))
                    IF @ID <> '' 
                        BEGIN
                            INSERT  INTO @IDsTable
                                    ( [ID] )
                            VALUES  ( CAST(@ID AS VARCHAR) )
                        END
                    SET @IDsList = RIGHT(@IDsList, LEN(@IDsList) - @Pos)
                    SET @Pos = CHARINDEX(',', @IDsList, 1)
                END
        END 
    RETURN
END

GO

这是函数调用的方式:

SELECT * FROM dbo.SplitStrings('123,548,198,547,965')

答案 8 :(得分:0)

Try this:

    DECLARE @Ids varchar(50);
    SET @Ids = '1,2,3,5,4,6,7,98,234';
    
    SELECT * 
    FROM sometable 
    WHERE ','+@Ids+',' LIKE '%,'+CONVERT(VARCHAR(50),tableid)+',%';