我编写了一个用于插入姓名和电子邮件地址的存储过程:
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
作为一个例子,我将传递值
@name
= ramesh,suresh,rahul
@email
= ramesh@gmail.com,suresh@gmail.com,rahul@gmail.com
在插入之前我们检查条件电子邮件地址是否存在,假设电子邮件地址存在则不会插入表中。
现在我的问题是我将通过示例解释。 ramesh@gmail.com 和 suresh@gmail.com 是新的电子邮件地址,这两个电子邮件地址都会插入到表中,因此返回值 1 rahul@gmail.com已存在于表中,因此它将插入表中,因此返回值将为 0 ,输出@return值将为 0 ,但我们已插入2封电子邮件地址所以我需要 @return值应为1
所以我的问题是,如果在一个电子邮件地址的任何地方插入表格,如果一个电子邮件地址也插入输出应 @ return = 1
答案 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