【问题标题】:How to return value 1 stored procedure如何返回值 1 存储过程
【发布时间】:2016-12-06 03:39:09
【问题描述】:

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

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

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

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

【问题讨论】:

  • 你看过 MERGE() 吗?它似乎非常适合此类问题。与@@ROWCOUNT 配对
  • 你到底为什么要使用这样的循环来插入数据?这应该是基于集合的方法。这让我想知道您的分离器是否也是基于循环的解决方案。以下是循环分离器的一些更好的替代方案。 sqlperformance.com/2012/07/t-sql-queries/split-strings

标签: sql-server stored-procedures


【解决方案1】:

您需要的东西被称为“闩锁”(古老的)或flag variable,这很常见。

标志变量(在本例中为@result)应在循环外初始化,然后在出现条件时设置(在本例中,插入记录)。当跳过任何后续记录时,不应触及该变量。这样,它就充当了一种或门。

像这样:

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 条件,因为在跳过记录时您无需执行任何操作。

【讨论】:

    【解决方案2】:

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

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

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

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

    但我个人建议您实际上将您的 spT 更改为每个名称/电子邮件对调用一次。这是一种更好、更清洁的方法。

    HTH

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-29
      • 2014-06-18
      • 1970-01-01
      • 2014-08-06
      • 1970-01-01
      相关资源
      最近更新 更多