简体   繁体   中英

SQL Server 2008 Trigger Errors

I need some help with a database trigger that I just can't get working. Disclosure : I'm not a DBA and don't claim any expertise, but I've been tasked with getting this done..

That said, here is the problem statement:

I have a database with a few tables that we want to track updates/inserts/deletes on. The trigger should catch the "before" and the "after" values of some columns, take both along with some additional information (mentioned below) and add them to a versioncontrol table.

I've put together what I think should work based on tutorial and other information available on various sites, but no matter what I do when I try to create the trigger it always throws an error:

Msg 311, Level 16, State 1, Procedure tr_taskconstructs_U, Line 38
Cannot use text, ntext, or image columns in the 'inserted' and 'deleted' tables.

The column layout for the table I'm applying the trigger to is very simple:

ResourceID (PK, nvarchar(38))
AML (ntext, null)

I want to catch changes to the AML column and insert the changes into a table, as follows:

id (int, not null),
ResourceID (nvarchar(38)),
TableName (nvarchar(50)),
DateTime (datetime),
Type (varchar(20)),
Before (ntext),
After (ntext)

My code is as follows:

CREATE TRIGGER tr_taskconstructs_U ON taskconstructs AFTER UPDATE
AS 
BEGIN

SET NOCOUNT ON;

    DECLARE @before nvarchar(max), 
        @after nvarchar(max), 
        @resource nvarchar(50)

IF UPDATE(AML)
BEGIN
    SELECT @before = d.AML,
            @after = i.AML,
            @resource = d.ResourceID
    FROM inserted i
        INNER JOIN deleted d on d.ResourceID = i.ResourceID

    INSERT INTO versioncontrol
    VALUES (@resource, 'taskconstructs', GetDate(), 'Update', @before, @after)

END

END
GO

It always fails with the error mentioned above. I tried changing the datatypes of the variables, etc, with the same result. I've tried commenting out almost everything and it also has the same error. I'm obviously missing something, but am not able to figure out what.

Any help would be appreciated.

change the table to use the nvarchar(max) datatype instead. Ntext is deprecated anyhow and should not be used going forward

Like said in the other answer ntext , along with text and image are deprecated datatypes which triggers can't really work with. They will be removed for future versions of SQL Server so your best solution would be to change them to NVARCHAR(MAX) , VARCHAR(MAX) or VARBINARY(MAX) respectively.

http://msdn.microsoft.com/en-us/library/ms189799.aspx

However, if that's not a possibility for you at the moment - INSTEAD OF trigger can work with them so you can try to intercept the updates and do them from trigger, filling your log table in the process.

But, before I show you example of that, I must point out a big mistake you have in your existing trigger - You have wrote the query that works only on single row from INSERTED which is not good as UPDATE can often update more then 1 row at the time. Even if your app is not designed to allow it, you should never write trigger asuming it is always going to be single row.

So your trigger should have looked like this: (and should look like this if/after you change that column)

CREATE TRIGGER tr_taskconstructs_U ON taskconstructs AFTER UPDATE
AS 
BEGIN

SET NOCOUNT ON;

IF UPDATE(AML)
BEGIN

    INSERT INTO versioncontrol
    SELECT ResourceID, 'taskconstructs', GetDate(), 'Update'. d.AML, i.AML
    FROM inserted i
    INNER JOIN deleted d on d.ResourceID = i.ResourceID

END

END
GO

Now, for the INSTEAD OF TRIGGER:

CREATE TRIGGER tr_taskconstructs_U ON taskconstructs INSTEAD OF UPDATE
AS 
BEGIN

    --insert log
    INSERT INTO versioncontrol 
    SELECT i.ResourceID, 'taskconstructs', GetDate(), 'Update', d.AML, i.AML
    FROM inserted i
     INNER JOIN taskconstructs d on d.ResourceID = i.ResourceID

    --update actual data
    UPDATE t 
    SET t.AML = i.AML
    from taskconstructs t
    INNER JOIN INSERTED i ON i.ResourceID = t.ResourceID 

END
GO

SQLFiddle DEMO

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM