我将一个列表传递给一个存储过程,它以我的数据库中定义的类型(表)的形式存在。所以参数in是:
CREATE TYPE [dbo].[DomainNames] AS TABLE(
[Domain] [nvarchar](255) NULL
)
由此我需要插入/删除两个表。第一个是表格:
CREATE TABLE [dbo].[CompanyDomains](
[Id] [int] IDENTITY(1,1) NOT NULL,
[CompanyId] [int] NOT NULL,
[EmailDomain] [nvarchar](255) NOT NULL
)
对于将传入列表与CompanyDomains表相关联的所有操作,都有传入的CompanyId参数,它适用于CompanyDomains表中的行,其中CompanyDomains.CompanyId =传入的@CompanyId参数。
对于传入列表中同样位于CompanyDomains中的所有行 - 我什么都不做。
将传入列表中不在表CompanyDomains.EmailDomain中的任何域添加到表CompanyDomains中。除了没有更新操作之外,还有一些upsert。
对于CompanyDomain中不在列表中的任何行,我需要从CompanyDomains表中删除该行,并在此表中插入一个新条目,其中CompanyName为传入的@CompanyName参数。
CREATE TABLE [dbo].[DeletedCompany](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Domain] [nvarchar](255) NOT NULL,
[CompanyName] [nvarchar](255) NOT NULL,
)
我说upsert因为如果该表中有一行具有相同的域名,那么我更新CompanyName。否则我会插入一条新记录。
我可以在C#中使用三个不同的调用(select,delete,insert / update)完成所有这些操作。但我还在学习存储过程,而且我不知道如何做到这一点。我似乎也不知道要搜索的字样,因为我没有运气。
我的存储过程必须在Sql Server 2008& Sql Azure,但无需在别处运行。
谢谢 - 戴夫
答案 0 :(得分:0)
我们可以使用MERGE
根据连接条件进行更新/插入/删除
如果在源(输入域列表)中找不到,则第一个MERGE
插入新行或删除一行
删除的域名存储在临时表
中如果不存在具有此类名称的记录,则第二个MERGE
会将已删除的记录插入DeletedCompany。
CREATE PROCEDURE AddUpdateDomains
@TableVariable DomainNames READONLY,
@CompanyId int,
@CompanyName nvarchar(255)
AS
BEGIN
DECLARE @DeletedDomains Table
(
emailDomain nvarchar(255)
)
MERGE
[CompanyDomains] T
USING
@TableVariable S
ON
T.CompanyId = @CompanyId
AND T.EmailDomain = S.Domain
WHEN NOT MATCHED BY TARGET THEN
INSERT VALUES ( @CompanyId, S.Domain)
WHEN NOT MATCHED BY SOURCE AND T.CompanyId = @CompanyId THEN
DELETE
OUTPUT deleted.EmailDomain INTO @DeletedDomains;
MERGE
DeletedCompany T
USING
@DeletedDomains S
ON T.CompanyName = @CompanyName
AND T.Domain = S.emailDomain
WHEN NOT MATCHED THEN
INSERT VALUES ( S.emailDomain, @CompanyName);
END