2012-09-27 67 views
0

以下是我们的某个SQL表中用于任何插入/更新操作的触发器。 99/100倍这个触发但是每一个现在工作得很好,然后我们收到此错误信息:尝试使用触发器插入数据时出错T-SQL

无法将NULL值插入列“TransactionDate”,表 “AgentResourcesU01.dbo.TransactionLog”;列不允许有空值。
INSERT失败。该语句已终止。

你可以从INSERT语句看到,在我们的事务日志表中的列TransactionDate, Operator, TableName, Action, TableStringUserId。我在开始的SELECT语句中设置变量@transDate,因此对我而言,应该没有办法让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'不为null? – Taryn

+0

是的,我们只是做到了。 – NealR

+0

结果是什么? – Taryn

回答

1

为了证明马克的时候,你可以在基于集合的方式做到这一点,没有所有这些讨厌的变数,而且如果检查:

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]我认为你有一个INSERT/UPDATE/DELETE触发器,当有人试图从基表中删除行时,触发器中的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]要更正您的触发器(见Marc的评论),请阅读192页 - 亚历克斯·库兹涅佐夫的书(防守数据库编程与SQL Server 199 :Amazon,Red Gate - PDF)。

相关问题