如何返回值1存储过程

时间:2016-12-05 18:06:10

标签: sql-server stored-procedures

我编写了一个用于插入姓名和电子邮件地址的存储过程:

CREATE PROCEDURE [dbo].[usp_Referral_Email]
    @user_key varchar(36),
    @name nvarchar(100),    
    @email nvarchar(500),
    @result int output
AS
BEGIN
    DECLARE @username Nvarchar(500)
    DECLARE @useremail Nvarchar(500)
    DECLARE @CusrsorID CURSOR

    SET @CusrsorID = CURSOR FOR
        SELECT Value,Value1
        FROM ufn_split_string(@name,@email) 

    OPEN @CusrsorID

    FETCH NEXT FROM @CusrsorID INTO @username, @useremail

    WHILE @@FETCH_STATUS = 0
    BEGIN
        declare @user nvarchar(36)

        begin try
        begin transaction trans_Referral_Email      

            IF NOT EXISTS (SELECT 1 FROM dbo.C_User_Credentials 
                           WHERE email = @useremail)
            BEGIN
                IF NOT EXISTS (SELECT 1 FROM dbo.Referral_Email 
                               WHERE R_Email = @useremail)
                BEGIN
                    INSERT INTO dbo.Referral_Email (CFK_C_UP_key, R_Name, R_Email)
                    VALUES (@user_key, @username, @useremail)               

                    SET @result = 1
                END
                ELSE
                BEGIN
                    SET @result = 0
                END
            END
            ELSE
            BEGIN
                SET @result = 0
            END

            COMMIT transaction trans_Referral_Email
        end try
        begin catch
            rollback transaction trans_Referral_Email
            set @result=ERROR_MESSAGE()
        end catch


        FETCH NEXT FROM @CusrsorID INTO @username, @useremail
    END

    CLOSE @CusrsorID
    DEALLOCATE @CusrsorID
END

作为一个例子,我将传递值

  1. @name = ramesh,suresh,rahul
  2. @email = ramesh@gmail.com,suresh@gmail.com,rahul@gmail.com
  3. 在插入之前我们检查条件电子邮件地址是否存在,假设电子邮件地址存在则不会插入表中。 现在我的问题是我将通过示例解释。 ramesh@gmail.com suresh@gmail.com 是新的电子邮件地址,这两个电子邮件地址都会插入到表中,因此返回值 1 rahul@gmail.com已存在于表中,因此它将插入表中,因此返回值将为 0 ,输出@return值将为 0 ,但我们已插入2封电子邮件地址所以我需要 @return值应为1

    所以我的问题是,如果在一个电子邮件地址的任何地方插入表格,如果一个电子邮件地址也插入输出应 @ return = 1

2 个答案:

答案 0 :(得分:1)

你需要的东西被称为" latch" (古老的)或flag variable,并且很常见。

标志变量(在这种情况下,@result)应该在循环外部初始化,然后在出现条件时设置(在这种情况下,插入记录)。跳过任何后续记录时,不应触及该变量。这样它就像一个OR门。

像这样:

CREATE PROCEDURE [dbo].[usp_Referral_Email]
    @user_key varchar(36),
    @name nvarchar(100),    
    @email nvarchar(500),
    @result int output
AS
BEGIN
    DECLARE @username Nvarchar(500)
    DECLARE @useremail Nvarchar(500)
    DECLARE @CusrsorID CURSOR

    SET @CusrsorID = CURSOR FOR
        SELECT Value,Value1
        FROM ufn_split_string(@name,@email) 

    OPEN @CusrsorID

    FETCH NEXT FROM @CusrsorID INTO @username, @useremail
    SET @result = 0  --<--- Will stay 0 until one or more rows are inserted

    WHILE @@FETCH_STATUS = 0
    BEGIN
        declare @user nvarchar(36)

        begin try
        begin transaction trans_Referral_Email      

            IF NOT EXISTS (SELECT 1 FROM dbo.C_User_Credentials 
                           WHERE email = @useremail)
            BEGIN
                IF NOT EXISTS (SELECT 1 FROM dbo.Referral_Email 
                               WHERE R_Email = @useremail)
                BEGIN
                    INSERT INTO dbo.Referral_Email (CFK_C_UP_key, R_Name, R_Email)
                    VALUES (@user_key, @username, @useremail)               

                    SET @result = 1  --<--- Will stay 1 for the rest of its lifespan, even if other rows are not inserted
                END
            END

            COMMIT transaction trans_Referral_Email
        end try
        begin catch
            rollback transaction trans_Referral_Email
            set @result=ERROR_MESSAGE()
        end catch


        FETCH NEXT FROM @CusrsorID INTO @username, @useremail
    END

    CLOSE @CusrsorID
    DEALLOCATE @CusrsorID
END

注意我删除了一堆ELSE条件,因为在跳过记录时你不需要做任何事情。

答案 1 :(得分:0)

您正尝试使用1个存储过程调用来处理/插入多个用户,并且您不能使用单个输出INT字段来返回多个用户的插入状态。

最好在应用程序级别拆分@name和@email参数,并将只有一对名称和电子邮件传递给您的(修改过的)存储过程。然后,您必须为每个名称/电子邮件对多次从应用程序级别调用spT。

如果您仍想使用单个spT进行批量用户插入,则必须将每个插入状态记录到临时表或表变量中,然后在spT端,您必须从该临时表或表变量中进行SELECT 。

这种方式在应用程序级别,您将为每个名称/电子邮件输入对返回一个状态行。

但我个人建议你实际更改你的spT,每个名字/电子邮件对都要调用一次。这是一种更好,更清洁的方法。

HTH