Sql触发器父-子

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

我正试图找出创建触发器的最佳方法,但我在使用SQLServer2008时遇到了麻烦 我希望创建一个存储所有电话号码的中心表。该表应包含客户表中的所有客户号码。 数字有一个子表numbercustomer,它将数字链接到一个或多个客户。 我的桌子:

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,它将数字链接到一个或多个客户。这似乎很奇怪。多个客户将共享一个号码?你确定这不是相反的方式吗,例如,一个客户可以有多个数字?一个客户可以而且确实有一个或多个数字也许我应该说,我们正在尝试使用它进行报告,在这种情况下,它是多对多的。我是否正确理解您的代码可以工作,但您只是在寻求优化?如果是这样的话,也许你应该在你的问题中更清楚地说明这一点。我的代码适用于数字,但我不知道如何调整它以同时检查和输入子表