473,383 Members | 1,855 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

Trigger assistance

I have a trigger that I created to log changes in one table to another
table but it is horribly inefficient.

I am hoping that someone with more experience than I can see a way to
make this trigger more efficient.

------------

ALTER TRIGGER tContacts_ChangeLog
ON dbo.Contacts
FOR UPDATE
AS

SET NOCOUNT ON

DECLARE @tablename varchar(20),
@record_id_column varchar(30),
@colname varchar(30),
@colvalue varchar(8000),
@insertstmt varchar(1500),
@username varchar(20)

SELECT @tablename = 'Contacts'
SELECT @record_id_column = 'ContactID'

DECLARE columns_cursor CURSOR LOCAL FOR
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @tablename
AND (POWER(2, (ORDINAL_POSITION-1) % 8) & CONVERT(INT,
SUBSTRING(COLUMNS_UPDATED(), (ORDINAL_POSITION-1)/8 + 1, 1))) <> 0

SELECT * INTO #del FROM deleted
SELECT * INTO #ins FROM inserted
SELECT @username = RIGHT(SYSTEM_USER, LEN(SYSTEM_USER) -
CHARINDEX('\',SYSTEM_USER))

OPEN columns_cursor

FETCH NEXT FROM columns_cursor INTO @colname

WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @insertstmt = 'INSERT INTO ' + @tablename + '_ChangeLog (
recordid, fieldname, changedfrom, changedto, username, datetime ) ' +
'SELECT d.' + @record_id_column + ', ''' + @colname + ''', d.' +
@colname + ', i.' + @colname + ', ''' + @username + ''', GETDATE()' +
'FROM #del d INNER JOIN #ins i ON d.' + @record_id_column + ' = i.' +
@record_id_column + ' WHERE (i.' + @colname + ' <> d.' + @colname + ')'
+
' OR (i.' + @colname + ' IS NOT NULL AND ' + 'd.' + @colname + ' IS
NULL) OR (i.' + @colname + ' IS NULL AND ' + 'd.' + @colname + ' IS NOT
NULL)'

-- INSERT INTO Debug (value) VALUES( @insertstmt )

EXEC( @insertstmt )

FETCH NEXT FROM columns_cursor INTO @colname
END

CLOSE columns_cursor
DEALLOCATE columns_cursor

Jul 23 '05 #1
8 1790
Matt (gg@tolton.com) writes:
I have a trigger that I created to log changes in one table to another
table but it is horribly inefficient.

I am hoping that someone with more experience than I can see a way to
make this trigger more efficient.


Looks like you are into auditing. You could possibly make the code
somewhat more efficient by getting the metadata from the system tables
directly, rather than INFORMATION_SHECMA. Also, always make your
cursors STATIC (or INSENSITIVE), unless you have a good reason for
using something else.

You can also improve performance by replacing the temp tables with
table variables. Creating temp tables in triggers can be expensive,
if there are many operations on the table in the same transaction,
particularly if you use SELECT INTO. Declaring primary keys in the
table variables may also be a good thing.

But it's never going to be that effecient. And be aware of that you
need to grant INSERT permissions to all users who will update this
table, even if they access the table through a stored procedure.

So you may have to change approach entirely. Actually, there are
auditing products out there. To mention two, Red Matrix has SQLAudit
(which uses triggers) and Lumigent has Entegra (which gets information
from the transaction log).

--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 23 '05 #2
Matt (gg@tolton.com) writes:
I have a trigger that I created to log changes in one table to another
table but it is horribly inefficient.

I am hoping that someone with more experience than I can see a way to
make this trigger more efficient.


Looks like you are into auditing. You could possibly make the code
somewhat more efficient by getting the metadata from the system tables
directly, rather than INFORMATION_SHECMA. Also, always make your
cursors STATIC (or INSENSITIVE), unless you have a good reason for
using something else.

You can also improve performance by replacing the temp tables with
table variables. Creating temp tables in triggers can be expensive,
if there are many operations on the table in the same transaction,
particularly if you use SELECT INTO. Declaring primary keys in the
table variables may also be a good thing.

But it's never going to be that effecient. And be aware of that you
need to grant INSERT permissions to all users who will update this
table, even if they access the table through a stored procedure.

So you may have to change approach entirely. Actually, there are
auditing products out there. To mention two, Red Matrix has SQLAudit
(which uses triggers) and Lumigent has Entegra (which gets information
from the transaction log).

--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 23 '05 #3
You can avoid such horrors by creating static trigger code for each table.
It isn't too difficult to write a scrpt to generate the triggers for you
based on the info schema views. In the long run the time spent designing
such a script is sure to prove worthwhile.

--
David Portas
SQL Server MVP
--
Jul 23 '05 #4
You can avoid such horrors by creating static trigger code for each table.
It isn't too difficult to write a scrpt to generate the triggers for you
based on the info schema views. In the long run the time spent designing
such a script is sure to prove worthwhile.

--
David Portas
SQL Server MVP
--
Jul 23 '05 #5
The reason I'm using temporary tables is that I have to use EXEC to
execute the select statement, so the inserted and deleted tables aren't
available, but temporary tables are. Can I reference a table variable
like that (in an EXEC statement)? I didn't think that I could.

Fortunately, since I'm using an application role, granting the INSERT
permission to the role is not a big deal.

Thankyou very much for the help.

Jul 23 '05 #6
I am going to stick with this solution until performance on it becomes
an issue, at which point I'll be forced to do as you say. Thankyou for
the advice.

Jul 23 '05 #7
Matt (gg@tolton.com) writes:
The reason I'm using temporary tables is that I have to use EXEC to
execute the select statement, so the inserted and deleted tables aren't
available, but temporary tables are. Can I reference a table variable
like that (in an EXEC statement)? I didn't think that I could.
That's correct. I was sort of suggesting that you would abandon the
dynamic SQL as well.
I am going to stick with this solution until performance on it becomes
an issue, at which point I'll be forced to do as you say. Thankyou for
the advice.


That's a little funny, since in your first post, you complained that
the current scheme was ineffecient.

--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 23 '05 #8
My apologies for the confusion..right now it is not causing a problem,
but I can see that it certainly could in the future. I like to make
things as efficient as possible, whether they're causing a problem
right now or later...I was hoping someone could suggest something that
was not static. At this moment, it isn't worth it to me to write the
static trigger code because of a lack of time, but I'll be sure to jump
on it if I run into any issues.

Thanks for your time.

Jul 23 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Mavis | last post by:
Seems the XMLBulkload does not support the "Trigger". But I really need to execute some rules after bulk load, anyone can give me some hints about this? I wonder whether I can fire a trigger in my...
2
by: William F. O'Neill | last post by:
Am using SQL Server 2000 on WINXP Pro. Have a requirement to change some Oracle triggers to SQL 2000. I have modied this one Insert Trigger, but get an error when I attempt to compile: CREATE...
6
by: Antanas | last post by:
I am puzzled by the following behavior. If stored procedure PROC1 is called 2 times in trigger TRIG1, then I get error during trigger firing: SQL0723N An error occurred in a triggered SQL...
6
by: Jchick | last post by:
Im a newbie with a sql table in a MSDE database that contains fields of CustName, BrokerName, Type, Status. I am trying to write a trigger that does this: 1. When a new record in a table is...
0
by: gshawn3 | last post by:
Hi, I am having a hard time creating a Trigger to update an Oracle database. I am using a SQL Server 2005 Express database on a Win XP Pro SP2 desktop, linked to an Oracle 10g database on a...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.