How do I read inserted text data in a trigger?

Hello,

I am using SQL Server 2000 with Service Pack 3 installed.

I have a trigger. The source table for the trigger contains a text column.

I am trying to capture that text variable value into a local variable. Every combination I try I always get the error: Cannot use text, ntext, or image columns in the 'inserted' and 'deleted' tables.

The reason I am trying to do this, is that later in the trigger code, I want to insert this text data into a surrogate real table.

Below are my attempts.

DROP TRIGGER TRIns_client_contract_comments
GO
CREATE TRIGGER TRIns_client_contract_comments
ON client_contract_comments
FOR INSERT AS
BEGIN
declare @vclient_id numeric
declare @vclient_contract_num varchar
declare @vclient_service_type_cd char
declare @vcomment_type char

declare @vcomments varchar(8000)

-- TEXT INVALID FOR LOCAL VARIABLES declare @vtcomments text

declare @vlast_update_userid char
declare @vlast_update_dt datetime
/*
I ALWAYS GET THIS MESSAGE
Cannot use text, ntext, or image columns
in the 'inserted' and 'deleted' tables.
*/


declare @ptrval binary(16)
-- FAIL 'CANNOT USE' select @ptrval=textptr(comments) from inserted
-- FAIL 'CANNOT USE' select comments into #comments from inserted

-- declare @substr varchar(10)
-- FAIL CAN NOT USE' select @substr = upper(substring(comments,1,5)) from inserted

select @vclient_id = ins.client_id,
@vclient_contract_num = ins.client_contract_num,
@vclient_service_type_cd = ins.client_service_type_cd,
@vcomment_type = ins.comment_type,
-- FAIL 'CANNOT USE' @vcomments = ins.comments,
@vlast_update_userid = ins.last_update_userid,
@vlast_update_dt = ins.last_update_dt
from inserted ins


END
GO

Any ideas or workarounds?

Thanks.

AIMDBA

[1943 byte] By [AIMDBA] at [2007-12-19]
# 1
This is documented (as well as the solution) in the BOL under CREATE Trigger:

"In a DELETE, INSERT, or UPDATE trigger, SQL Server does not allow text, ntext, or image column references in the inserted and deleted tables if the compatibility level is set to 70. The text, ntext, and image values in the inserted and deleted tables cannot be accessed. To retrieve the new value in either an INSERT or UPDATE trigger, join the inserted table with the original update table. When the compatibility level is 65 or lower, null values are returned for inserted or deleted text, ntext, or image columns that allow null values; zero-length strings are returned if the columns are not nullable. "

If you got any problems using the suggestions mentioned in the BOL, just raise a hand.

HTH, Jens Suessmeyer.

http://www.sqlserver2005.de

JensSuessmeyer at 2007-9-9 > top of Msdn Tech,SQL Server,Transact-SQL...
# 2

Early, I said that I am using SQL Server 2000 with Service Pack 3. This is compatiblity 80 (not 65 and not 70).

The BOL solution for 80 is the following:

"If the compatibility level is 80 or higher, SQL Server allows the update of text, ntext, or image columns through the INSTEAD OF trigger on tables or views."

I can not write an INSTEAD OF trigger. This would break what I am trying to do.

Microsoft has a bug report on this 'inability of reading text data inside of a trigger.' The only possibly solution mentioned is to apply a hotfix.

In my environment, this would be applied to a production machine. I can not do this immediately. This means not this year, in 2006.

Do any more ideas or workarounds exist?

Thanks.

AIMDBA

AIMDBA at 2007-9-9 > top of Msdn Tech,SQL Server,Transact-SQL...
# 3

Why not an INSTEAD OF trigger? I can't think of anything you couldn't do in the instead of trigger (though it will bust identity usage functions, so you would have to change your code to just use the table's alternate key for access to get the last inserted row.)

Note also that your trigger would not work correctly right now for multiple rows. The variables would simply get the last row in the set.

Short of this, if you are not doing data valiation, consider just putting the key of the table in a queue and have an external process work on the rows asynchronously.

As for a bug report, I doubt there a hotfix because 2005 doesn't allow it either. It does allow varchar(max) (the replacement for text columns) in triggers.

# 4

Get the text data from the table itself, joining to inserted on the primary key, so you're only looking at inserted records. Remember that when the trigger fires, the insert has already occurred. If the trigger does a ROLLBACK, of course, it will be deleted.

You still can't declare a local text variable (until SQL 2005, where you can use varchar(max)), but you can at least inspect the data using substring(), or other functions that operate on text data. (I haven't actually tried this, but I don't see why it wouldn't work...)

Ken

khaley at 2007-9-9 > top of Msdn Tech,SQL Server,Transact-SQL...
# 5

Hi,

In my case I'm creating a trigger on the fly for auditing purposes. Everything works fine expect for the tables having text or ntext or image columns. This is a generic stored proc which takes a table name as the input and creates a trigger on the fly. Are there any alternatives how I can excape this error. I don't really care if I didn't read the text,image or ntext columns. But wouldn't want the stored proc to stop creating the trigger just for this reason.

Would appreciate if you could point me to any alternative

Thanks
Aravind Rajagopal

AravindRajagopal at 2007-9-9 > top of Msdn Tech,SQL Server,Transact-SQL...

SQL Server

Site Classified