4

[更新:使用 SQL Server 2005]

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

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

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'

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

4

9 回答 9

1

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

如果你在 Erland 和“Dynamic SQL”上做一个谷歌,他对它所包含的陷阱有很好的描述。

于 2009-02-05T18:45:20.320 回答
1

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

于 2009-02-05T18:45:24.097 回答
1

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)
于 2009-02-05T18:47:38.990 回答
1

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

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

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

于 2009-02-05T18:50:37.720 回答
0

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

JOIN ufn_CSVToTable(@PassedInIDs) uf ON database.ID = uf.[String]
于 2009-02-05T18:09:35.243 回答
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()')

那应该是一个开始

于 2009-02-05T18:36:52.850 回答
0

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

我最严格的实施是

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

    -
于 2009-02-05T19:20:28.067 回答
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')
于 2015-06-10T11:15:12.700 回答
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)+',%';
于 2021-07-09T02:39:22.713 回答