C# 使用in子句更新SQL Server中的多行
我有这样一个存储过程:C# 使用in子句更新SQL Server中的多行,c#,sql,sql-server,C#,Sql,Sql Server,我有这样一个存储过程: CREATE PROCEDURE Resume @UserID nvarchar(100) AS BEGIN SET NOCOUNT ON; update Candidate set Approved = 'y' where UserId_I in (@UserID) END GO 在这种情况下,@UserID是字符串格式的。我从代码中以字符串形式发送参数@UserID的值为1,2,3 我犯了一个错误 将nvarchar值“1,2,3”转换为
CREATE PROCEDURE Resume
@UserID nvarchar(100)
AS
BEGIN
SET NOCOUNT ON;
update Candidate set Approved = 'y' where UserId_I in (@UserID)
END
GO
在这种情况下,@UserID是字符串格式的。我从代码中以字符串形式发送参数@UserID的值为1,2,3
我犯了一个错误
将nvarchar值“1,2,3”转换为数据类型int时,转换失败
请解决此问题请使用命令更新
你可以用多种方式来做。您可以定义一个表类型并通过该表类型传递用户ID列表。请参见以下问题: 您还可以在WHILE循环中拆分逗号处的字符串,并将ID添加到临时表中。然后你可以用。。。在中,从@tentable中选择UID。粗略算法:
DECLARE @tempTable TABLE (UID INT)
WHILE ([Length of @UserID > 0])
BEGIN
IF ([@UserID contains comma?])
BEGIN
[GET STRING UNTIL COMMA]
[CONVERT TO INT AND INSERT INTO @tempTable]
[REMOVE STRING AND COMMA FROM @UserID]
END ELSE
BEGIN
[CONVERT @UserID TO INT AND INSERT INTO @tempTable]
SET @UserID = ''
END
END
您也可以使用EXEC方法,但我倾向于不使用EXEC和从外部传递的参数—您可以将代码打开以进行SQL注入。我要执行的最小检查是@UserID参数是否只包含数字、逗号和空格。发生错误的原因是无法将字符串@UserID用作IN运算符的右运算符。IN操作符需要一个集作为右操作符-在这种情况下,您需要一组int来判断UserId_I是否是该集的一部分 这里可以做两件事:要么为@UserID参数使用一个表值参数,要么编写一个函数将@UserID字符串转换/拆分为一个表/一组整数,在这种情况下,您将得到如下结果:
...WHERE @UserId_I IN dbo.ParseIntSet(@UserId);
尝试使用比子查询性能更好的临时表
DECLARE @userIds NVARCHAR(MAX)
SET @userIds ='1,2,3,4,5,6'
CREATE table #TempUser
(
userId Int
)
DECLARE @SplitOn VARCHAR(1)
SET @SplitOn = ','
While (Charindex(@SplitOn,@userIds)>0)
Begin
Insert Into #TempUser (userId)
Select
userId = ltrim(rtrim(Substring(@userIds ,1,Charindex(@SplitOn,@userIds )-1)))
Set @userIds = Substring(@userIds,Charindex(@SplitOn,@userIds)+1,len(@userIds))
End
Insert Into #TempUser (userId)
Select Data = ltrim(rtrim(@userIds))
SELECT * FROM #TempUser
现在,您可以使用此临时表更新记录。您可以尝试下面给出的演示
CREATE PROCEDURE [dbo].[Proc_Name] @CSVConnectivityIds NVARCHAR(MAX)
WHILE len(@CSVConnectivityIds) > 0
BEGIN
INSERT INTO tblName
VALUES (left(@CSVConnectivityIds, charindex(',', @CSVConnectivityIds + ',') - 1))
SET @CSVConnectivityIds = stuff(@CSVConnectivityIds, 1, charindex(',', @CSVConnectivityIds + ','), '')
END
我希望这将有助于您对于拆分@UserID参数,您可以使用
请参见中的演示。中的多个单独参数在逻辑上不同于碰巧包含逗号的单个字符串参数。SQL与几乎所有其他编程语言一样,不会神奇地决定检查字符串并更改它。正确的解决方案是首先不要传递字符串(理想情况下传递一个表值参数或XML文档),而是传递设计为包含多个值的内容。毫无疑问,您将获得指向在服务器上创建拆分函数的答案或接近票数,但这确实是错误的方法。这当然也是一个选项,但请注意此处SQL注入的可能性-
CREATE PROCEDURE [dbo].[Proc_Name] @CSVConnectivityIds NVARCHAR(MAX)
WHILE len(@CSVConnectivityIds) > 0
BEGIN
INSERT INTO tblName
VALUES (left(@CSVConnectivityIds, charindex(',', @CSVConnectivityIds + ',') - 1))
SET @CSVConnectivityIds = stuff(@CSVConnectivityIds, 1, charindex(',', @CSVConnectivityIds + ','), '')
END
CREATE PROCEDURE Resume
@UserID nvarchar(100)
AS
BEGIN
SET NOCOUNT ON;
UPDATE Candidate
SET Approved = 'y'
WHERE UserId_I IN
(SELECT Split.a.value('.', 'int')
FROM (SELECT CAST ('<M>' + REPLACE(@UserID , ',', '</M><M>') + '</M>' AS XML) AS val
) AS A CROSS APPLY val.nodes('/M') AS Split(a)
)
END
GO