Sql触发器父-子
我正试图找出创建触发器的最佳方法,但我在使用SQLServer2008时遇到了麻烦 我希望创建一个存储所有电话号码的中心表。该表应包含客户表中的所有客户号码。 数字有一个子表numbercustomer,它将数字链接到一个或多个客户。 我的桌子:Sql触发器父-子,sql,sql-server,triggers,Sql,Sql Server,Triggers,我正试图找出创建触发器的最佳方法,但我在使用SQLServer2008时遇到了麻烦 我希望创建一个存储所有电话号码的中心表。该表应包含客户表中的所有客户号码。 数字有一个子表numbercustomer,它将数字链接到一个或多个客户。 我的桌子: CREATE TABLE [Campaign].[Number]( [NumberID] [int] IDENTITY(1,1) NOT NULL, [Number] [varchar](15) NOT NULL, [LastU
CREATE TABLE [Campaign].[Number](
[NumberID] [int] IDENTITY(1,1) NOT NULL,
[Number] [varchar](15) NOT NULL,
[LastUpdated] [timestamp] NOT NULL,
CONSTRAINT [Pk_Number] PRIMARY KEY CLUSTERED
(
[NumberID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [Campaign].[NumberCustomer](
[CustomerNumberID] [int] IDENTITY(1,1) NOT NULL,
[NumberID] [int] NOT NULL,
[CustomerID] [int] NOT NULL,
CONSTRAINT [PK_CustomerNumber] PRIMARY KEY CLUSTERED
(
[CustomerNumberID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [Crm].[Customer](
[CustomerID] [int] IDENTITY(30000,1) NOT NULL,
[FirstName] [varchar](255) NULL,
[LastName] [varchar](255) NULL,
[MobileNumber] [varchar](11) NULL,
[LandlineNumber] [varchar](11) NULL,
CONSTRAINT [PK__Customer__8CB286B91CF15040] PRIMARY KEY CLUSTERED
(
[CustomerID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
我希望触发器检查数字表,如果不存在,则插入数字。然后检查触发器的第二部分,如果未向客户提供链接,则插入。
我可以用触发器更新数字表,如下所示,但我担心性能
CREATE TRIGGER [Crm].[Customer_Number_Updated] ON [Crm].[Customer]
AFTER Update, INSERT
NOT FOR REPLICATION AS
SET NoCount On
DECLARE
@AuditTime DATETIME,
@IsDirty BIT
SET @AuditTime = GetDate()
SET @IsDirty = 0
Begin Try
INSERT INTO
[Campaign].[Number]([Number])
select
number
from
(
Select
i.MobileNumber as number
From
inserted i
join
deleted d
on
i.CustomerID = d.CustomerID
and
isnull(i.MobileNumber ,'') <> isnull(d.MobileNumber,'')
UNION
Select
i.LandlineNumber as number
From
inserted i
join
deleted d
on
i.CustomerID = d.CustomerID
and
isnull(i.LandlineNumber ,'') <> isnull(d.LandlineNumber,'')
UNION
Select
i.AlternateContactNumber as number
From
inserted i
join
deleted d
on
i.CustomerID = d.CustomerID
and
isnull(i.AlternateContactNumber ,'') <> isnull(d.AlternateContactNumber,'')
) as nums
WHERE NOT EXISTS
(
SELECT
*
FROM
[Campaign].[Number] cn
WHERE
cn.Number = nums.number
)
End try
Begin Catch
IF ERROR_NUMBER() <> 2627
DECLARE @ErrorMessage NVARCHAR(4000), @ErrorSeverity INT, @ErrorState INT;
SET @ErrorMessage = ERROR_MESSAGE();
SET @ErrorSeverity = ERROR_SEVERITY();
SET @ErrorState = ERROR_STATE();
RAISERROR(@ErrorMessage,@ErrorSeverity,@ErrorState) with log;
End Catch
GO
任何帮助都将不胜感激
Rob您的触发器适用于更新,但不适用于插入:您正在加入删除和插入,当您插入新记录时,删除中没有任何内容。 您应该在触发器中执行插入和更新,或者执行合并 这是带有插入和仅更新try块中的代码的代码 insert使用deleted进行左连接,并检查id是否为null反半连接,相当于没有texists 更新程序使用inserted执行内部联接,以仅检查更新记录
Begin Try
-- insert new records
INSERT INTO
[Campaign].[Number]([Number])
select
i.MobileNumber
from inserted i
left join deleted d on i.customerid = d.customerid
where d.customerid is null -- new records (no deleted record)
and not exists( select Number from [Campaign].[Number] c where c.number = i.MobileNumber)
-- union the same for LAndLineNumber
-- union the same for AlternateNumber
-- update existing number
update [Campaign].[Number]
set Number = i.MobileNumber
-- set LandLineNumber too
-- and AlternateNumber
from [Campaign].[Number] n
left join deleted d on d.MobileNumber = n.Number
inner join inserted i on i.CustomerId = d.CustomerId
End try
数字有一个子表numbercustomer,它将数字链接到一个或多个客户。这似乎很奇怪。多个客户将共享一个号码?你确定这不是相反的方式吗,例如,一个客户可以有多个数字?一个客户可以而且确实有一个或多个数字也许我应该说,我们正在尝试使用它进行报告,在这种情况下,它是多对多的。我是否正确理解您的代码可以工作,但您只是在寻求优化?如果是这样的话,也许你应该在你的问题中更清楚地说明这一点。我的代码适用于数字,但我不知道如何调整它以同时检查和输入子表