SQL Server 存储过程中的返回值

15

我有一个存储过程,其中包含一个if语句。如果计数的行数大于0,则应将唯一的输出参数@UserId设置为0。

但是它只在查询的第二部分返回值。

@EmailAddress varchar(200),
@NickName varchar(100),
@Password varchar(150),
@Sex varchar(50),
@Age int,
@EmailUpdates int,
@UserId int OUTPUT
IF 
    (SELECT COUNT(UserId) FROM RegUsers WHERE EmailAddress = @EmailAddress) > 0
    BEGIN
        SET @UserId = 0
    END
ELSE
    BEGIN
        INSERT INTO RegUsers (EmailAddress,NickName,PassWord,Sex,Age,EmailUpdates) VALUES (@EmailAddress,@NickName,@Password,@Sex,@Age,@EmailUpdates)
        SELECT SCOPE_IDENTITY()
    END

END

1
“返回查询的第二部分值”是什么意思?输出参数不会作为记录集返回。 - Andrey Gurinov
4个回答

9
你有两种选择:
更改: SET @UserId = 0 为 SELECT @UserId 这将以与 IF 语句的第二部分相同的方式返回值。
或者,由于 @UserId 被设置为输出,更改: SELECT SCOPE_IDENTITY()SET @UserId = SCOPE_IDENTITY() 这取决于你之后如何访问数据。如果你希望该值在结果集中,则使用 SELECT。如果你想之后访问 @UserId 参数的新值,则使用 SET @UserId
既然您认为第二个条件是正确的,那么您可以编写以下查询(无需更改此查询之外的任何内容):
@EmailAddress varchar(200),
@NickName varchar(100),
@Password varchar(150),
@Sex varchar(50),
@Age int,
@EmailUpdates int,
@UserId int OUTPUT
IF 
    (SELECT COUNT(UserId) FROM RegUsers WHERE EmailAddress = @EmailAddress) > 0
    BEGIN
        SELECT 0
    END
ELSE
    BEGIN
        INSERT INTO RegUsers (EmailAddress,NickName,PassWord,Sex,Age,EmailUpdates) VALUES (@EmailAddress,@NickName,@Password,@Sex,@Age,@EmailUpdates)
        SELECT SCOPE_IDENTITY()
    END

END

嗨,我尝试设置第二部分来设置@UserId,但那也没起作用。 - andrew slaughter
@andrewslaughter 请看我的修改。现在两个条件都使用了SELECT,这将在你的结果集中返回一个值。从你的问题来看,似乎这就是你从这个查询中访问该值的方式。 - Curtis

4
我建议提前初始化未来索引值,这在多工作、某些导出等情况下非常有用。只需创建额外的“User_Seq”表:具有两个字段:id唯一索引SeqVal nvarchar(1)。然后创建以下存储过程,从此存储过程生成ID值并将其放入新的用户行中即可!
CREATE procedure [dbo].[User_NextValue]
as
begin
    set NOCOUNT ON


    declare @existingId int = (select isnull(max(UserId)+1, 0)  from dbo.User)

    insert into User_Seq (SeqVal) values ('a')
    declare @NewSeqValue int = scope_identity()     

    if @existingId > @NewSeqValue 
    begin  

        set identity_insert User_Seq  on
        insert into User_Seq (SeqID) values (@existingId)     
        set @NewSeqValue = scope_identity()     
    end

    delete from User_Seq WITH (READPAST)

return @NewSeqValue

end

根据MSDN的建议:您还应该避免使用返回代码来返回应用程序数据。 - Franziee

2

尝试以这种方式调用您的过程:

DECLARE @UserIDout int

EXEC YOURPROC @EmailAddress = 'sdfds', @NickName = 'sdfdsfs', ..., @UserId = @UserIDout OUTPUT

SELECT @UserIDout 

@AndreyGurinov 我不明白这怎么解决问题...第二个条件 UserId 仍将是 NULL。 - Curtis
嗨,感谢您的回复。如果我从对象资源管理器中执行存储过程并放置参数,第一次运行它,我会在结果窗格中得到:(无列名)64(这是最后插入的用户ID) &UserId NULL 返回值0如果我再次运行它,我只会得到:&UserId 0 返回值0 - andrew slaughter
这帮助我找出如何调用存储过程。 - Water

0
@EmailAddress varchar(200),
@NickName varchar(100),
@Password varchar(150),
@Sex varchar(50),
@Age int,
@EmailUpdates int,
@UserId int OUTPUT
DECLARE @AA INT
SET @AA=(SELECT COUNT(UserId) FROM RegUsers WHERE EmailAddress = @EmailAddress)

IF @AA> 0
    BEGIN
        SET @UserId = 0
    END
ELSE
    BEGIN
        INSERT INTO RegUsers (EmailAddress,NickName,PassWord,Sex,Age,EmailUpdates) VALUES (@EmailAddress,@NickName,@Password,@Sex,@Age,@EmailUpdates)
        SELECT SCOPE_IDENTITY()
    END

END

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接