Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用in子句更新SQL Server中的多行_C#_Sql_Sql Server - Fatal编程技术网

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