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是字符串格式。我发送的参数@UserID1,2,3来自代码作为字符串。

我得到了错误

将 nvarchar 值“1,2,3”转换为数据类型 int 时转换失败。

请解决这个

4

6 回答 6

3

你可以通过多种方式做到这一点。您可以定义表类型并通过该表类型传递用户 ID 列表(请参阅此问题:INSERT using LIST into Stored Procedure)。

您还可以在循环中拆分逗号处的字符串WHILE并将 ID 添加到临时表中。然后你可以使用... IN (SELECT UID FROM @tempTable). 粗略算法:

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参数是否仅包含数字、逗号和空格。

于 2013-07-12T07:36:35.717 回答
2

请使用EXECUTE (Transact-SQL)命令更新。

CREATE PROCEDURE Resume 
    -- Add the parameters for the stored procedure here
    @UserID nvarchar(100)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
    exec ('update Candidate set Approved=''y'' where UserId_I in ('+@UserID+')')
END
GO
于 2013-07-12T07:36:33.233 回答
2

尝试使用性能比子查询更好的临时表

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

现在您可以使用这个临时表来更新您的记录。

于 2013-07-12T07:47:49.163 回答
1

对于拆分 @UserID 参数,您可以使用XQuery value() 方法

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

见演示SQLFiddle

于 2013-07-12T08:57:18.203 回答
0

发生错误是因为您不能使用字符串 (@UserID) 作为 IN 运算符的右手运算符。IN 运算符需要一个 SET 作为右手运算符 - 在这种情况下,您需要一组整数来判断 UserId_I 是否是该集合的一部分。

您可以在这里做两件事:要么为@UserID 参数使用表值参数,要么编写一个将@UserID 字符串转换/拆分为表/整数集的函数,在这种情况下,您将得到类似的东西:

...WHERE @UserId_I IN dbo.ParseIntSet(@UserId);
于 2013-07-12T07:38:37.810 回答
0

您可以尝试下面给出的演示...

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

我希望这能帮到您

于 2013-07-12T08:24:56.340 回答