I want to check when my trigger is turned on and off in SQL Server 2005 database. I have created a trigger which inserts entry into new table whenever there is change in specific column. But I received a complaint from client saying that log is not maintained for all updated records in Log Table.
I feel it may be due to trigger is turned off while updating some records so it may not have been recorded in log table.
So how to see log record of whether trigger is turned on or off?
Thanks in advance.
Not quite clear what you're looking for.
Do you want to be able to check at any given time whether the trigger is on or off? In that case, use this statement:
SELECT is_disabled
FROM sys.triggers
WHERE name = 'your-trigger-name-here'
If you want to track when a given trigger is disabled, you could write a DDL trigger that catches the ALTER_TRIGGER event and makes a note of who and when a given trigger was disabled.
I put this answer for whom may search for this question.
You can use this statement to see more detail and the last modify date and time of trigger.
SELECT *
FROM sys.triggers
WHERE name = 'your-trigger-name-here'
Related
I have the following trigger to save the changes to a log table. However, it will not catch the changes triggered the trigger? Or is there another solution?
alter trigger trigger_xxx on table1 after delete, update, insert
as
begin
declare #lastVersion bigint = coalesce((select max(SYS_CHANGE_VERSION) from [log]), 0)
insert into [log]
([SourceColumnDescriptionPattern], SYS_CHANGE_VERSION, SYS_CHANGE_OPERATION, SYS_CHANGE_COLUMNS, SYS_CHANGE_CONTEXT)
SELECT [SourceColumnDescriptionPattern], SYS_CHANGE_VERSION, SYS_CHANGE_OPERATION, SYS_CHANGE_COLUMNS, SYS_CHANGE_CONTEXT
FROM changetable(changes [table1], #lastVersion) as ct
end
Change Tracking is intended for synchronization purposes. For example you can use it to find out if a application side cache needs to be refreshed. Therefore you do not want for that information to show up before the transaction is committed. As your trigger executes within the transaction the changes are not visible yet.
Why are you trying to duplicate the information available in Change Tracking? Cant you just use those functions and DMVs instead of your own?
Assuming you have a good reason, your best bet is probably to use a trigger and capture the affected primary key together with other pertinent information like a timestamp yourself. However there is no real good way to enforce that trigger being executed before all others so you might still end up in the same situation. You could try sp_settriggerorder in your case: http://msdn.microsoft.com/en-us/library/ms186762.aspx It might be enough in your situation.
If you can figure out this one you are a true SQL guru! It's one of the weirdest things I've ever seen.
I've added a trigger to a table in our database. The server is SQL 2008. The trigger doesn't do anything particularly tricky. Just changes a LastUpdated field in the table when certain fields are changed. It's a "After Update" trigger.
There is a large C++ legacy app that runs all kind of huge queries against this database. Somehow (I've got absolutely no idea how) it is deleting this trigger. It doesn't delete any other triggers and I'm certain that it's not explicitly dropping the trigger or table. The developers of this app don't even know anything about my triggers.
How is this possible??
I've tried running a trace using SQL Server Profiler and I've gone through each command that it's sending and run them using SQL Management Studio but my trigger is not affected. It only seems to happen when I run the app. WTF :(
UPDATE:
Sorry I don't want to waste your time. I just realised that if I change the name of the trigger then it doesn't get deleted. Furthermore if I modify the trigger so it doesn't do anything at all then it still gets deleted. From this I can only guess that the other devs are explicitly deleting it but I've searched the trace for the trigger name and it's not there. I'll hassle them and see what they say. Thanks for the suggestions.
UPDATE 2:
The other devs reckon that they are not deleting it explicitly. It doesn't exist in sys.objects or sys.triggers so it's not a glitch with SSMS. So confused :( Guess I'll just rename it and hope for the best? Can't think of anything else to try. A few comments below have asked if the trigger is being deleted or just disabled or not working. As I stated, it's being deleted completely. Also, the problem is not related to the actual contents of the trigger. As I stated, it I remove the contents and replace with some extremely simple code that doesn't do anything then it is still deleted.
Cheers
Mark
Thoughts:
To delete a trigger requires ALTER permission = shouldn't be used by an app
Triggers can be disabled with ALTER TABLE
Triggers can be confused by testing for ##ROWCOUNT at the beginning to trap dummy updates etc
Is the trigger coded for single rows only and appears not to run
Does the trigger exists in sys.objects/sys.triggers: don't rely on Object Explorer in SSMS
A trigger can be deleted if the table is dropped and re-created
A trigger won't fire for TRUNCATE TABLE
I had an identical issue which I tracked down to a creation script missing a final GO statement.
Script 1
IF EXISTS (....)
DROP PROC MyProc
GO
CREATE PROC MyProc
.....
/* GO statement is missing */
Script 2
IF EXISTS (....)
DROP TRIGGER MyDisappearingTrigger
GO
CREATE TRIGGER MyDisappearingTrigger
.....
GO
When I inspected MyProc in the object explorer it looked like this:
CREATE PROC MyProc
AS
...
IF EXISTS (....)
DROP TRIGGER MyDisappearingTrigger
GO
So this meant that every time the stored proc was called the trigger was also deleted.
check with MERGE command in table it will cause triggers get error
Pretty general question regarding triggers in SQL server 2005.
In what situations are table triggers fired and what situations aren't they?
Any code examples to demonstrate would be great.
I'm writing a audit based databases and just want to be aware of any situations that might not fire off the triggers that I have set up for update, delete and insert on my tables.
A example of what I mean,
UPDATE MyTable SET name = 'test rows' WHERE id in (1, 2, 3);
The following statement only fires the update trigger once.
When do you want them to fire?
CREATE TRIGGER AFTER ACTION
That runs after the action (insert update delete) being committed. INSTEAD OF fires the trigger in place of the action.
One of the biggest gotchas with triggers is that they fire whenever an action is performed, even if no rows are affected. This is not a bug, and it's something that can burn you pretty quickly if you aren't careful.
Also, with triggers, you'll be using the inserted and deleted tables. Updated rows are listed in both. This throws a lot of folks off, because they aren't used to thinking about an update as a delete then insert.
The MSDN documentation actually has a pretty in-depth discussion about when triggers fire and what effect they have here.
On 2008 you can use built in Change Data Capture
Also There are quite a few situations when triggers do not fire, such as:
· A table is dropped.
· A table is truncated.
· Settings for nested and/or recursive triggers prevent a trigger from firing.
· Data is bulk loaded, bypassing triggers.
The following statement only fires the update trigger once.
Any action type statement only fires the trigger once no matter how many rows are affected, triggers must be written to handle multiple row inserts/updates/deletes.
If your trigger depends on only one row at a time being in the inserted or deleted pseudotables, it will fail. And worse it will not fail with an error, it will simply not affect all the rows you want affected by whatever the trigger does. Do not fix this through a loop or a cursor in a trigger, change to set-based logic. A cursor in a trigger can bring your entire app to a screeching halt while a transaction of 500,000 records processes and locks up the table for hours.
Bulk inserts by pass triggers unless you specify to use them. Be aware of this because if you let them by pass the trigger you will need code to make sure whatever happens in the trigger also happens after the bulk insert. Or you need to call the bulk inserts with the FIRE_TRIGGERS option.
I thought I'd highlight from the link Eric posted a situation in which a trigger would not fire:
Although a TRUNCATE TABLE statement is in effect a DELETE, it cannot activate a trigger because the operation does not log individual row deletions. However, only those with permissions on a table to execute a TRUNCATE TABLE need be concerned about inadvertently circumventing a DELETE trigger with a TRUNCATE TABLE statement.
One of my database fields in a table is getting modified by some piece of code. I just can't figure out where!
So, I was wondering if there's a way I can find out.
I'm using SQL 2008. Can Profiler be used to find out if a particular field is getting updated? How?
What about a Trigger? If using a trigger (eg. on UPDATE) can you determine what code called it? How can the trigger 'notify me' of this? Email/file?
Yes, an "AFTER UPDATE" trigger on that particular table and field might give you some clues as to when and why the field gets changed.
From Books Online:
CREATE TRIGGER reminder
ON Person.Address
AFTER UPDATE
AS
IF ( UPDATE (StateProvinceID) OR UPDATE (PostalCode) )
BEGIN
RAISERROR (50009, 16, 10)
END;
GO
A trigger can execute basically any T-SQL code - if you have database mail set up correctly, it could send you an e-mail, yes. Or it can write an audit entry into another table or something like that.
EDIT: If you need to find out which statements updated your column, you might be actually better off running a trace on the server, limited to that specific table, and just trace what's happening there. I don't think a trigger can give you that information (which code caused the update to happen).
Marc
Determining the last Update to or Select against a table (without a trigger!)
http://sqlblogcasts.com/blogs/tonyrogerson/archive/2007/06/03/determining-the-last-update-to-or-select-against-a-table-without-a-trigger.aspx
Yes, you can use a trigger to execute some code (keep track of who updated the table, email you, etc.) when a table is updated. See this link: Track Updates with a Database Trigger
edit: originally posted the wrong link
The table doesn't have a last updated field and I need to know when existing data was updated. So adding a last updated field won't help (as far as I know).
SQL Server 2000 does not keep track of this information for you.
There may be creative / fuzzy ways to guess what this date was depending on your database model. But, if you are talking about 1 table with no relation to other data, then you are out of luck.
You can't check for changes without some sort of audit mechanism. You are looking to extract information that ha not been collected. If you just need to know when a record was added or edited, adding a datetime field that gets updated via a trigger when the record is updated would be the simplest choice.
If you also need to track when a record has been deleted, then you'll want to use an audit table and populate it from triggers with a row when a record has been added, edited, or deleted.
You might try a log viewer; this basically just lets you look at the transactions in the transaction log, so you should be able to find the statement that updated the row in question. I wouldn't recommend this as a production-level auditing strategy, but I've found it to be useful in a pinch.
Here's one I've used; it's free and (only) works w/ SQL Server 2000.
http://www.red-gate.com/products/SQL_Log_Rescue/index.htm
You can add a timestamp field to that table and update that timestamp value with an update trigger.
OmniAudit is a commercial package which implments auditng across an entire database.
A free method would be to write a trigger for each table which addes entries to an audit table when fired.