2013-11-14 3 views
0

Я пытаюсь разработать лучший способ создания триггера, но я ударил кирпичную стену с использованием SQL-сервера 2008 Я хочу создать центральную таблицу, в которой хранятся все телефонные номера (номер), которые должны содержать все номера клиентов из таблицы клиентов. Номера имеют дочерний стол номер клиента, который связывает число с одним или несколькими клиентами. Мои таблицы:Sql trigger parent child

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] 

Я хотел бы на курок, чтобы проверить номер таблицы и вставить номер, если его нет. Вторая часть триггера shuld затем проверяет и вставляет, если нет ссылки на клиента. Я могу получить таблицу чисел, чтобы обновить с помощью триггера, как показано ниже, но я уверен в производительности.

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 

Любая помощь будет очень признательна?

Роб

+0

** Числа есть ребенок таблица numbercustomer, который связывает ряд к одному или нескольким клиентам. ** Это кажется странным. Число будет разделяться между несколькими клиентами? Вы уверены, что это не так, например, e.i. у клиента может быть несколько номеров? – wvdz

+0

У клиента может быть и есть одно или несколько номеров, возможно, я должен был сказать, что мы пытаемся использовать это для отчетности, и в этом случае его много для многих действительно –

+0

Правильно ли я понимаю, что ваш код работает, но вы просто ищете оптимализация? Возможно, вы должны сделать это более ясным в своем вопросе, если это так. – wvdz

ответ

0

Ваш триггер работает для UPDATE, но не для вставки: вы присоединяетесь УДАЛИТЬ и вставляли и при вставке новых записей, нет ничего в удален. Вы должны сделать INSERT и UPDATE в вашем триггере или сделать MERGE.

Вот код с вставкой и обновление (только код в блоке TRY)

Вкладыша сделать левое соединение с удалено и убедитесь, что идентификатор является нулевым (анти пола присоединиться, что эквивалентен не texists).

Обновления сделать внутреннее соединение с вставлена ​​для проверки записей обновления только

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