Tsql t-sql将逗号分隔的字符串转换为int,而不使用用户创建的函数
我正在传递一个int的列表(逗号分隔) 即Tsql t-sql将逗号分隔的字符串转换为int,而不使用用户创建的函数,tsql,Tsql,我正在传递一个int的列表(逗号分隔) 即1,2,3,4 但是我得到了一个错误,因为列表是一个字符串,我正在与一个int字段进行比较。是否有一种方法可以将列表转换为int,而不使用用户创建的函数 注意:employeeID为INT declare @intArray varchar(200) SELECT * FROM tbl_Employee WHERE employeeID IN ( @intArray ) 错误是“无法将类型varchar转换为int”您尝试的不仅是将字符串转换为int
1,2,3,4
但是我得到了一个错误,因为列表是一个字符串,我正在与一个int字段进行比较。是否有一种方法可以将列表转换为int,而不使用用户创建的函数
注意:employeeID为INT
declare @intArray varchar(200)
SELECT *
FROM tbl_Employee
WHERE employeeID IN ( @intArray )
错误是“无法将类型varchar转换为int”您尝试的不仅是将
字符串
转换为int
,而且将多个int
转换为一个。您是否希望您的SELECT
将返回数组中列出的所有员工的姓名和ID
我意识到您希望在没有函数的情况下执行此操作。然而,这就是我目前的做法,效果很好。从我的回答中你可以随心所欲
此代码使用while
循环,如果您使用的是SQL 2005/2008,则可能会将其改进为递归CTE。您可以将函数的输出用作内部联接的表,该表允许您快速过滤
/*
************************************************************************************************************************
Name: ConvertDelimitedListIntoTable
Description: Converts a list of delimited values into a table for use like a dynamic IN statment
Modification History
Date Author Description
========== ============ ====================================
2009-01-31 B. Williams Initial Creation
************************************************************************************************************************
*/
ALTER FUNCTION [dbo].[ConvertDelimitedListIntoTable] (
@list NVARCHAR(MAX) ,@delimiter CHAR(1) )
RETURNS @table TABLE (
item VARCHAR(255) NOT NULL )
AS
BEGIN
DECLARE @pos INT ,@nextpos INT ,@valuelen INT
SELECT @pos = 0 ,@nextpos = 1
WHILE @nextpos > 0
BEGIN
SELECT @nextpos = CHARINDEX(@delimiter,@list,@pos + 1)
SELECT @valuelen = CASE WHEN @nextpos > 0 THEN @nextpos
ELSE LEN(@list) + 1
END - @pos - 1
INSERT @table ( item )
VALUES ( CONVERT(INT,SUBSTRING(@list,@pos + 1,@valuelen)) )
SELECT @pos = @nextpos
END
DELETE FROM @table
WHERE item = ''
RETURN
END
使用:
使用计数表也可能有一种快速的方法。您不想将该列表转换为int,而是转换为int列表
没有用于该操作的cast操作符或函数,但您可以使用动态SQL绕过它
基本上是你写的
EXECUTE('SELECT * FROM tbl_Employee WHERE employeeID IN ('+@intArray+')')
不过要注意SQL注入攻击 如果您使用的是sql server 2016及更高版本,请使用字符串分割
declare @intArray varchar(200)
Set @intArray = '3,4,6,7'
SELECT *
FROM tbl_Employee
WHERE employeeID IN (select * from STRING_SPLIT(@intArray, ','))
这是做OP想要做的事情的一种很好的本地方式。请记住,随着员工名单和ID
s的增加,
中的短语变得越来越无效。在2005/2008年,首选存在。另外,动态SQL不能被缓存,因此执行速度永远不会像其他语句那样快。@Brad:动态语句和其他语句一样被缓存。只要不更改查询文本,缓存的计划就会被执行。当然,如果查询执行得非常频繁,这里的不同ID列表将是一个问题。EXISTS将需要一些(临时)表来存储搜索到的ID。如果您只是拥有列表(即,从一个web应用程序中,用户可以通过复选框选择某些员工),IN仍然是您的最佳选择。我同意EXISTS
在这里并不实用,我只是想指出,如果表或列表中的较大,则首选IN。了解到SQL确实缓存了动态SQL的计划(对于每个更改),这是很好的。但我认为这种缓存在很大程度上是可以折扣的,因为查询将频繁更改。如果不是,为什么选择使用动态SQL?我讨厌将所有内容都变成红色:-(我希望有另一种方法。不过谢谢你的输入。最后这是正确的答案。lol。SQL Server的哪个版本?你能更改调用你的sp的代码吗?@Damien SQL Server 2005。是的,我能更改调用我的sp.rats的代码。对于2008年,我建议改为使用表值参数。对吗nage使第一个解决方案在存储过程中工作。感谢这一解决方案!不仅您的SQL Server应该是2016,而且兼容性级别应该是130或更高。请阅读更多。这一解决方案正在工作。这也是一个很短的解决方案。在我的情况下工作
declare @intArray varchar(200)
Set @intArray = '3,4,6,7'
SELECT *
FROM tbl_Employee
WHERE employeeID IN (select * from STRING_SPLIT(@intArray, ','))