我正在将联系人对象列表(List<Contact>
从C#传递到SQL Server存储过程:
为捕获此列表,我在SQL Server中使用了用户定义的表类型,如下所示:
现在在存储过程中,我需要做以下事情。
如果数据库中的tblContact
表包含具有当前电子邮件地址(具有当前联系人记录/迭代)的记录,则需要获取tblContact
记录ContactId
并将其分配给当前的Contact
迭代记录;否则,使用该电子邮件地址(不存在)向tblContact插入新记录,并将其contactId值分配给当前联系人记录/迭代次数tblContact字段(因为contactId是TblContact的主键,我可以这样做
SET @contactId = (SELECT SCOPE_IDENTITY());
)。
最后选择修改后的联系人记录
在实现上面列出的第二步时,我需要一些帮助,这是我到目前为止所写的,
ALTER PROCEDURE [dbo].[UpdateMailjetDetails]
@contacts Contact READONLY
AS
BEGIN
SET NOCOUNT ON;
-- 1. Loop (cursor) though contacts list passed to stored procedure
DECLARE @contactEmail varchar(1000);
DECLARE cur CURSOR FOR
SELECT Email FROM @contacts
OPEN cur
FETCH NEXT FROM cur INTO @contactEmail;
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @contactId INT = (SELECT TOP(1) ContactId
FROM tblContact
WHERE EmailAddress = @contactEmail);
IF (@contactId != '')
BEGIN
SELECT 'Exists - ' + CONVERT(VARCHAR, @contactId);
-- 2 assign contact Id to current contact.TblContactId
END
ELSE
BEGIN
INSERT INTO tblContact (EmailAddress, DateCreated)
VALUES (@contactEmail, GETDATE());
SET @contactId = (SELECT SCOPE_IDENTITY());
-- 2 new @contactId value to current contact.TblContactId
END
FETCH NEXT FROM cur INTO @contactEmail;
END
CLOSE cur
DEALLOCATE cur
-- 3
SELECT * FROM @contacts
END
这就是我执行存储过程的方式:
DECLARE @return_value int
DECLARE @input Contact;
INSERT INTO @input (Email, [Name], TblContactId, CompanyId, TblContactCompanyId)
VALUES ('a@a.com', 'a', null, null, null),
('b@a.com', 'b', null, 1, 1),
('a@gmail.com', 'aa', null, 1, 1),
('b@hotmail.com', 'bb', null, 1, 1)
EXEC @return_value = [dbo].[UpdateMailjetDetails]
@contacts = @input
SELECT 'Return Value' = @return_value
GO
因此,如上所述,在执行存储过程之后,它需要使用其TblContactId
(现有或新插入的)值来打印所有联系人记录。
对此表示感谢的任何帮助或指导。谢谢。
答案 0 :(得分:3)
如果我理解正确,则希望获取输入电子邮件地址的列表,如果该电子邮件地址尚不存在,请在目标表中插入任何电子邮件地址,然后在目标表中输出原始地址列表及其对应的数据?您根本不需要游标,以下应该可以满足您的需要,并且可能会更好地执行:
CREATE PROC dbo.UpdateMailjetDetails (
@contacts dbo.Contact READONLY
)
AS
INSERT INTO dbo.tblContact (EmailAddress, DateCreated)
SELECT c.Email, SYSDATETIME()
FROM @contacts c
WHERE NOT EXISTS (
SELECT 1
FROM dbo.tblContact t
WHERE t.EmailAddress = c.Email
);
SELECT c.Email, t.[Name], t.tblContactId, c.CompanyId, t.CompanyId AS tblContactCompanyId
FROM @contacts c
LEFT OUTER JOIN dbo.tblContact t ON t.EmailAddress = c.Email;
我的某些假设可能在此处稍有偏离,但这应作为起点。请注意,如果您对目标表的电子邮件地址列没有唯一的约束,那么末尾的结果可能会包含比您最初提供的更多的行,因为匹配的行可能会超过一个。请注意,如果您要执行其他操作(例如,如果该行存在则进行更新),则可以用merge语句替换insert语句。
答案 1 :(得分:0)
我使用如下表变量来完成此操作。
-- store the output in the below table
DECLARE @outputContacts TABLE (
Email NVARCHAR(512) NULL,
[Name] NVARCHAR(512) NULL,
TblContactId bigint NULL,
CompanyId int null,
TblContactCompanyId bigint null
);
现在,我使用光标循环表值联系列表,并在必要时进行插入,最后插入插入到输出表,如下所示。以下是SP。
ALTER PROCEDURE [dbo].[UpdateMailjetDetails]
@contacts Contact READONLY
AS
BEGIN
SET NOCOUNT ON;
-- store the output in the below table
DECLARE @outputContacts TABLE (
Email NVARCHAR(512) NULL,
[Name] NVARCHAR(512) NULL,
TblContactId bigint NULL,
CompanyId int null,
TblContactCompanyId bigint null
);
-- 1. Loop (cursor) though contacts list passed to stored procedure
DECLARE @contactEmail varchar(1000);
DECLARE @contactName NVARCHAR(512);
DECLARE @contactTblContactId bigint;
DECLARE @contactCompanyId int;
DECLARE @contactTblContactCompanyId bigint;
DECLARE cur CURSOR FOR SELECT Email, [Name], TblContactId, CompanyId, TblContactCompanyId FROM @contacts;
OPEN cur;
FETCH NEXT FROM cur INTO @contactEmail, @contactName, @contactTblContactId, @contactCompanyId, @contactTblContactCompanyId;
WHILE @@FETCH_STATUS = 0 BEGIN
DECLARE @contactId int = (select top(1) ContactId from tblContact where EmailAddress = @contactEmail);
IF (@contactId != '')
BEGIN
select 'Exists - ' + convert(varchar, @contactId);
END
ELSE
BEGIN
insert into tblContact (EmailAddress, DateCreated) values (@contactEmail, GETDATE());
SET @contactId = (SELECT SCOPE_IDENTITY());
END
-- insert to output table
insert into @outputContacts (Email, [Name], TblContactId, CompanyId, TblContactCompanyId)
values (@contactEmail, @contactName, @contactId, @contactCompanyId, @contactTblContactCompanyId);
FETCH NEXT FROM cur INTO @contactEmail, @contactName, @contactTblContactId, @contactCompanyId, @contactTblContactCompanyId;
END
CLOSE cur;
DEALLOCATE cur;
-- 3
select * from @outputContacts;
END