动态 SQL 逗号分隔值查询

发布于 2024-07-13 15:20:42 字数 696 浏览 12 评论 0原文

[更新:使用 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'

我在这里做错了什么吗? 感谢您的帮助。

[Update: Using SQL Server 2005]

Hi, what I want to do is query my stored procedure with a comma-delimited list of values (ids) to retrieve rows of data.

The problem I am receiving is a conversion error:

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

The statement in my where-clause and error is:

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

Note: database.ID is of int type.

I was following the article at:

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

but did not complete because of the error.

In my execution script I have:

...
@PassedInIDs= '1,5'

Am I doing something wrong here?
Thank you for your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

葬シ愛 2024-07-20 15:20:42

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

如果你用 Google 搜索 Erland 和“Dynamic SQL”,他对其中的陷阱有很好的描述。

I would strongly suggest that you use the second method from that link. Create a user-defined function that turns your comma-delimited string into a table, which you can then select from easily.

If you do a Google on Erland and "Dynamic SQL" he has a good writeup of the pitfalls that it entails.

不气馁 2024-07-20 15:20:42

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

For one, you are passing a string to the IN function in SQL. If you look back at the original article, you'll see that instead of issuing a direct SQL statement, it instead is building a string which is the SQL statement to execute.

-残月青衣踏尘吟 2024-07-20 15:20:42

SQL 中没有字符串计算。 这个:

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

变成::

database.ID IN (1,2,3)

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

database.ID IN ('Bob')

简而言之,您无法在 SQL 中执行您在此处尝试的操作。 但还有其他四种可能性:

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

There is no string evaluation in SQL. This:

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

will not be turned to:

database.ID IN (1,2,3)

just because the @PassedInIDs parameter happens to contain '1,2,3'. The parameter is not even looked at, because all you have is a string containing " + @PassedInIDs + ". Syntactically, this is equivalent to:

database.ID IN ('Bob')

To make it short, you can't do what you attempt here in SQL. But there are four other possibilities:

  1. you construct the SQL string in the calling language and abandon the stored procedure altogether
  2. you use a dynamic prepared statement with as many parameters in the IN clause as you pan to use
  3. you use a fixed prepared statement with, say, 10 parameters: IN (?,?,?,?,?,?,?,?,?,?), filling only as many as you need, setting the others to NULL
  4. you create a stored procedure with, say, 10 parameters and pass in as many as you need, setting the others to NULL: IN (@p1, @p2, ..., @p10).
白况 2024-07-20 15:20:42

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

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

在其中,您将解析字符串并执行到一组行的转换。 然后,您可以连接该表的结果,或使用 IN 来查看某个 id 是否在列表中。

I would create a CLR table-valued function:

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

In it, you would parse the string apart and perform a conversion to a set of rows. You can then join on the results of that table, or use IN to see if an id is in the list.

寂寞花火° 2024-07-20 15:20:42

您需要像对待表格一样对待 ufn_CSVToTable。 所以你可以加入这个函数:

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

You need to treat ufn_CSVToTable like it's a table. So you can join the function:

JOIN ufn_CSVToTable(@PassedInIDs) uf ON database.ID = uf.[String]
诗笺 2024-07-20 15:20:42

我建议在 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()')

这应该是一个开始

I suggest using XML for this in SQL 2005. Somewhat bulkier, but it can be easier. It allows you to select the XML into a table which can then be joined or inserted etc.

Look at Sql Server's OPENXML() if you haven't already.

For example, you could pass in something like:
'12...'

and then use:

exec sp_xml_preparedocument @doc OUTPUT, @xmlParam

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

That should be a start

时光暖心i 2024-07-20 15:20:42

这可以通过 Narayana 的文章中提到的 6 种方法来解决 将列表/数组传递给 SQL Server 存储过程< /a>

我最困难的实现是

声明 @statement nvarchar(256)
set @statement = 'select * from Persons where Persons.id in ('+ @PassedInIDs +')'
exec sp_executesql @statement

    -

this may be solved by 6 ways as mentioned in Narayana's article Passing a list/array to an SQL Server stored procedure

And my most strait forward implementation is

declare @statement nvarchar(256)
set @statement = 'select * from Persons where Persons.id in ('+ @PassedInIDs +')'
exec sp_executesql @statement

    -
春夜浅 2024-07-20 15:20:42

这是我发现和测试的:

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')

Here is what I have found and tested:

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

Here is how function Call:

SELECT * FROM dbo.SplitStrings('123,548,198,547,965')
凉栀 2024-07-20 15:20:42
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)+',%';
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)+',%';
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文