Триггер SQL Server INSERT для установки начального синтаксиса дат - PullRequest
1 голос
/ 03 апреля 2012

Я просмотрел несколько сообщений об обновлении триггера INSERT.Мой вопрос похож, но я настороженно отношусь к своему синтаксису в операторе UPDATE, особенно к тому, что не понимаю таблицу, которую продолжают называть INSERTED.

Код триггера обновит некоторые значения столбца даты только на INSERT (и благодаря некоторому коду, который я нашел здесь у одного из вас, гуру, есть логика для обработки столбца 'shipdueDate').

Уже существует увеличенное значение для номера счета-фактуры, основанное на настройке идентификатора, поэтому при создании новой строки номер счета-фактуры увеличивается на 1. Однако для облегчения работы администратора вДля добавления данных в накладную я подумал, что размещение начальных значений в полях orderdate, shipduedate и dateinvoiced позволит упростить ввод данных.

Это код, который я придумал

   CREATE TRIGGER Invoices_SetInitialDates ON dbo.Invoices FOR INSERT
   AS 
   BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
  SET NOCOUNT ON;
      DECLARE @fromDate DATETIME
  DECLARE @shipDate DATETIME
  DECLARE @daysToAdd int
    -- We promise a 7 day turn-around on orders, so it has to 
    -- ship on the 8th day
  SELECT @fromDate = CURRENT_TIMESTAMP, @DaysToAdd = 8
  SET datefirst 1

    -- code from stackoverflow to calculate the shipduedate based
    -- on week days. It doesn't have any logic for holidays, but it
    -- provides the Admin initial values to work with, and that she 
    -- can change in the new record.
      SELECT @shipDate =
        DATEADD(day,
        @daysToAdd%5 +
         CASE DATEPART(weekday,@fromDate) + @daysToAdd%5
           WHEN 6 THEN 2
           WHEN 7 THEN 1
         ELSE 0 END,
         DATEADD(week,@daysToAdd/5,@fromDate)
       )

       -- UPDATE statement for trigger here. I'm not sure
       -- here about a table called INSERTED, or if this will
       -- simply update the newly added record. This is where
       -- I believe I need guidance.
         UPDATE dbo.Invoices SET DateOrdered = @fromDate
         ,ShipDueDate = @shipDate
         ,DateInvoiced = @fromDate

       END
       GO

Заранее спасибо.Это отличный сайт с большим талантом SQL Server.

Ответы [ 2 ]

2 голосов
/ 03 апреля 2012

Если вас интересует только INSERT, то триггер абсолютно не нужен - просто определите значения по умолчанию для ваших столбцов!

ALTER TABLE dbo.Invoices
ADD CONSTRAINT DF_Invoices_DateOrdered DEFAULT (GETDATE()) FOR DateOrdered

ALTER TABLE dbo.Invoices
ADD CONSTRAINT DF_Invoices_DateInvoiced DEFAULT (GETDATE()) FOR DateInvoiced

ShipDueDate с его логикой вычислений немного сложнее, но, возможно, вы можете упростить это, чтобы также определить его как ограничение по умолчанию.

Ограничения по умолчанию предоставляют значения для ваших столбцов после INSERT, но только в том случае, если оператор INSERT явно не устанавливает для этих столбцов какое-либо другое значение.

0 голосов
/ 03 апреля 2012

Позвольте мне сначала объяснить, что вставлено (и удалено).В триггере есть две таблицы, которые содержат данные, которые вы собираетесь вставить или удалить.В обновлении старые значения удаляются, а новые добавляются.При удалении заполняется только удаленное.В вставку заполняется только вставленный.Теперь важно помнить, что вы никогда не можете положиться на триггер, чтобы в него была вставлена ​​или удалена только одна запись.Если вы вставили 100 записей в одну инструкцию вставки, то вставлено 100 записей.Поэтому код не будет работать должным образом, если вы предполагаете только одну запись.Подсказка в том, что вы не должны устанавливать значение из вставленной в скалярную переменную.

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

что-то вроде:

UPDATE inv
SET DateOrdered = @fromDate          
    ,ShipDueDate = @shipDate          
    ,DateInvoiced = @fromDate  
From dbo.Invoices inv
join inserted i on inv.id = i.id
...