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
Related
I've got database ApressFinancial which i created from the book. (Robin Dewson - Beginning SQL Server for Developers (The Expert's Voice in SQL Server) - 2014)
I was asked a question: "How to check the correctness of adding records to the transaction log?" (And there was Hint that i can use trigger instead of)
Could not figure out.
Thank you.
I think you need a INSTEAD OF INSERT trigger in order to catch all your inserted data.
Basically, you create a trigger, which is a special type of stored procedure that lets you hook some functionality inside the transaction that should perform the INSERT (instead of will cause the insert intent to not fulfill). The trigger will expose a special table (not sure this is the exact term, but it behaves like one) called inserted that contains the information that is supposed to be inserted.
A more relevant example can be found here.
NOTE: also take a look upon AFTER INSERT trigger, as this type allows values to be inserted and provide a mechanism to use the values to perform other operations.
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'
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
I'm using transactional replication with updatable subscription.
when I add a trigger for update in one of my tables which is chosen for replication in publisher, I encounter with this error:
Maximum stored procedure, function,trigger,
or view nesting level exceeded(limit 32)
My trigger code is
create trigger Isupdated
on tbl_worker
for update as
update tbl_worker SET
Isup=1
where id= (select id from inserted)
what's wrong?
It looks like you've written a recursive (aka nested) trigger.
Perhaps the trigger is causing an update on the table, causing the trigger to be fired again?
If you post the code, that would help us explain exactly what the issue is.
http://www.sqlmonster.com/Uwe/Forum.aspx/sql-server-programming/4752/Maximum-stored-procedure-function-trigger-or-view
The above link provides a solution to trigger nesting. This can be very helpful when you already have a trigger and then replication adds another one. I like this more than combining the triggers because it doesn't force you to mix code related to functionality and code related to replication.
To sum up the solution:
You can prevent the nested firing from happening by assigning the triggers
an order with sp_settriggerorder and add the following check to the
beginning of the trigger you set to fire first to prevent it being fired by
the other trigger:
CREATE TRIGGER....
IF TRIGGER_NESTLEVEL > 1 RETURN
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.