2012-09-27 3 views
0

Ниже приведен триггер, используемый в одной из наших таблиц SQL для любого действия вставки/обновления. 99/100 раз этот триггер работает просто отлично, однако каждый сейчас и потом мы получаем сообщение об ошибке:Ошибка при вставке данных с помощью триггера T-SQL

Не удается вставить значение NULL в столбец «TransactionDate», таблица «AgentResourcesU01.dbo.TransactionLog»; столбец не допускает нулей.
INSERT не работает. Заявление было прекращено.

Как видно из отчета Вставка столбцов в нашей таблице журнала транзакций являются TransactionDate, Operator, TableName, Action, TableString и UserId. Я устанавливаю переменную @transDate в инструкции SELECT открытия, так, как мне кажется, не должно быть никакого способа получить NULL там, где это происходит, если это не плохие данные.

Любые мысли?

BEGIN 
     SELECT @symetraNumber = SymetraNumber, @lastChangeOperator = LastChangeOperator, @transDate = LastChangeDate, @entityType = EntityType, 
     @firstName = FirstName, @lastName = LastName, @suffix = NameSuffix, @corpName = CorporateName, @controlId = ControlId 
     FROM inserted 

     IF @firstName IS NULL SET @firstName = 'NULL' 
     IF @lastName IS NULL SET @lastName = 'NULL' 
     IF @suffix IS NULL SET @suffix = 'NULL' 
     IF @corpName IS NULL SET @corpName = 'NULL' 
     IF @controlId IS NULL SET @controlId = 'NULL' 

     SET @tableString = 'SymNum:' + @symetraNumber + ' EntType:' + @entityType + ' Fname:' + @firstName + ' Lname:' + @lastname + ' Suff:' + @suffix + 
      ' CorpName:' + @corpName + ' ctrlId:' + @controlId 

     INSERT INTO TransactionLog (TransactionDate, Operator, TableName, Action, TableString, UserId) 
     VALUES (@transDate, 'Op', @tableName, @action, @tableString, @lastChangeOperator) 
    END 
+0

Вы подтвердили, что 'LastChangeDate' не является нулевым? – Taryn

+0

Да, мы просто это сделали. – NealR

+0

И каков был результат? – Taryn

ответ

1

Чтобы продемонстрировать точку Марка, вы можете сделать это таким образом, на основе набора, без всех этих противных переменных и IF проверяет:

INSERT dbo.TransactionLog 
(
    TransactionDate, 
    Operator, 
    TableName, 
    Action, 
    TableString, 
    UserId 
) 
SELECT 
    LastChangeDate, 
    'Op', 
    @TableName, 
    @action, 
    'SymNum:'  + COALESCE(SymetraNumber, 'NULL') 
    + ' EntType:' + COALESCE(EntityType, 'NULL') 
    + ' Fname:' + COALESCE(FirstName,  'NULL') 
    + ' Lname:' + COALESCE(LastName,  'NULL') 
    + ' Suff:'  + COALESCE(NameSuffix, 'NULL') 
    + ' CorpName:' + COALESCE(CorporateName, 'NULL') 
    + ' ctrlId:' + COALESCE(ControlId,  'NULL'), 
    LastChangeOperator 
FROM inserted; 

Если LastChangeDate в базовой таблице обнуляемым, либо метки он как NOT NULL, исправляет проблему, когда NULL встает, или и то, и другое. Триггер не должен знать об этом ограничении, но вы можете работать вокруг него, делая что-то вроде этого (если значение равно NULL, то установите его прямо сейчас):

... 
    UserId 
) 
SELECT 
    COALESCE(LastChangeDate, CURRENT_TIMESTAMP), 
    'Op', 
... 
0

[1] Я полагаю, что вы введите триггер DELETE INSERT/UPDATE/, и когда кто-то попытается удалить строки из базовой таблицы, таблица inserted из триггера будет иметь нулевые строки. Посмотрите на этот пример:

CREATE TABLE MyTableWithTrigger (
    MyID INT IDENTITY PRIMARY KEY, 
    LastUpdateDate DATETIME NOT NULL 
); 
GO 

CREATE TABLE TransactionLog (
    TransactionLogID INT IDENTITY PRIMARY KEY, 
    CreateDate DATETIME NOT NULL DEFAULT GETDATE(), 
    LastUpdateDate DATETIME NOT NULL, 
    MyID INT NOT NULL 
); 
GO 

CREATE TRIGGER trIUD_MyTableWithTrigger_Audit 
ON MyTableWithTrigger 
AFTER INSERT, UPDATE, DELETE 
AS 
BEGIN 
    DECLARE @LastUpdateDate DATETIME, @MyID INT; 
    SELECT @LastUpdateDate=i.LastUpdateDate, @MyID=i.MyID 
    FROM inserted i; 

    INSERT TransactionLog (LastUpdateDate, MyID) 
    VALUES (@LastUpdateDate, @MyID) 
END; 
GO 

PRINT 'Test 1' 
INSERT MyTableWithTrigger (LastUpdateDate) 
VALUES ('2011-01-01'); 
DELETE MyTableWithTrigger; 
SELECT * FROM MyTableWithTrigger; 
SELECT * FROM TransactionLog; 

Выход:

Msg 515, Level 16, State 2, Procedure trIUD_MyTableWithTrigger_Audit, Line 10 
Cannot insert the value NULL into column 'LastUpdateDate', table 'Test.dbo.TransactionLog'; column does not allow nulls. INSERT fails. 
The statement has been terminated. 

[2] Для того, чтобы исправить триггер (см комментарий Марка,), пожалуйста, читайте на страницах 192 - 199 из книги Алекса Кузнецова (Опорный Программирование баз данных с SQL Server : Amazon, Red Gate - PDF).

Смежные вопросы