TSQL Trigger on Subscriber Table - sql

I have a replicated subscriber table on SQL Server 2008. I have put a trigger on it that may or may not fail. The table is read only.
My question is :
If I use the following
SAVE TRANSACTION savepoint1
BEGIN TRY
...
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION savepoint1
END CATCH
to rollback the transaction if there is some error in my trigger (in the ... part), will SQL Server attempt to update or rollback the read only subscriber table still causing an error?
Thanks.

Are you putting the trigger on the publisher where it will work? And you don't want it to work on the subscriber but you don't know how to disable it?
If that's true, you might try the NOT FOR REPLICATION tag on the trigger:
http://msdn.microsoft.com/en-us/library/ms176072.aspx

Related

Prevent a sql trigger from rolling back original transaction on error

In Sql Server 2008 I've been asked to write triggers to do various types of logging in an application I've built. The problem is my SQL is rusty and sometimes some of the things I put in the triggers to do logging will unexpectedly error out. I intend to eventually work out all the errors but in the meantime my trigger code is breaking my application because if the trigger unexpectedly fails it rolls back the update or insert that triggered it breaking pieces of the application. I attempted to put a try catch block around the trigger code but it appears that doesn't do what I'm accustomed to it doing in other languages and it will rollback the original transaction even with that.
Does anybody know how/if you can write a trigger that when it errors it just dies gracefully and lets the transaction that triggered it complete?
You can enclose your trigger body code into a try-catch block.
CREATE TRIGGER tg
ON tt
AFTER DELETE
AS
set xact_abort off;
BEGIN TRY
sql_statements
END TRY
BEGIN CATCH
dies gracefully
END CATCH;
Remember to set xact_abort to off to avoid automatically rolling back current transaction.
sql fiddle sample

How to Ignoring errors in Trigger and Perform respective operation in MS SQL Server

I have created AFTER INSERT TRIGGER
Now if any case if an error occurs while executing Trigger. It should not effect Insert Operation on Triggered table.
In One word if any ERROR occurs in trigger it should Ignore it.
As I have used
BEGIN TRY
END TRY
BEGIN CATCH
END CATCH
But it give following error message and Rolled back Insert operation on Triggered table
An error was raised during trigger execution. The batch has been
aborted and the user transaction, if any, has been rolled back.
Interesting problem. By default, triggers are designed that if they fail, they rollback the command that fired it. So whenever trigger is executing there is an active transaction, whatever there was an explicit BEGIN TRANSACTION or not on the outside. And also BEGIN/TRY inside trigger will not work. Your best practice would be not to write any code in trigger that could possibly fail - unless it is desired to also fail the firing statement.
In this situation, to suppress this behavior, there are some workarounds.
Option A (the ugly way):
Since transaction is active at the beginning of trigger, you can just COMMIT it and continue with your trigger commands:
CREATE TRIGGER tgTest1 ON Test1 AFTER INSERT
AS
BEGIN
COMMIT;
... do whatever trigger does
END;
Note that if there is an error in trigger code this will still produce the error message, but data in Test1 table are safely inserted.
Option B (also ugly):
You can move your code from trigger to stored procedure. Then call that stored procedure from Wrapper SP that implements BEGIN/TRY and at the end - call Wrapper SP from trigger. This might be a bit tricky to move data from INSERTED table around if needed in the logic (which is in SP now) - probably using some temp tables.
SQLFiddle DEMO
You cannot, and any attempt to solve it is snake oil. No amount of TRY/CATCH or ##ERROR check will work around the fundamental issue.
If you want to use the tightly coupling of a trigger then you must buy into the lower availability induced by the coupling.
If you want to preserve the availability (ie. have the INSERT succeed) then you must give up coupling (remove the trigger). You must do all the processing you were planning to do in the trigger in a separate transaction that starts after your INSERT committed. A SQL Agent job that polls the table for newly inserted rows, an Service Broker launched procedure or even an application layer step are all going to fit the bill.
The accepted answer's option A gave me the following error: "The transaction ended in the trigger. The batch has been aborted.". I circumvented the problem by using the SQL below.
CREATE TRIGGER tgTest1 ON Test1 AFTER INSERT
AS
BEGIN
SET XACT_ABORT OFF
BEGIN TRY
SELECT [Column1] INTO #TableInserted FROM [inserted]
EXECUTE sp_executesql N'INSERT INTO [Table]([Column1]) SELECT [Column1] FROM #TableInserted'
END TRY
BEGIN CATCH
END CATCH
SET XACT_ABORT ON
END

MS SQL 2005- Rollback Update query

I'm using MS SQL Server 2005 enterprise edition. I executed an update query to get affect a record in a row and a column.
update HS_SM_USERACCOUNT
set ACCOUNTPOLICYTYPE=1
where EMP_NUMBER='000540' and USERID='03510410#'
Earlier the column called ACCOUNTPOLICYTYPE is holding value 1 for that particular condition in WHERE clause. Now I want to get the previous state without executing Update Query again.
Will ROLLBACK help me? Please help me on this.
No. It's changed. If you want to know what it was, restore from backup
Unless you executed the above query within the scope of a TRANSACTION - i.e. within BEGIN TRAN / COMMIT / ROLLBACK TRAN block, the ROLLBACK command is going to be of no use.
There is nothing you can do to get back the state that you updated with the above statement in such a situation except RESTORE an OLD backup of that table data

Execute Statements in a Transaction - Sql Server 2005

i need to update a database where some of the table have changed (columns have been added). I want to perform this action in a proper transaction. If the code executes without any problem then i will commit the changes otherwise i will rollback the database back to its original state.
I want to do something like this:
BEGIN TRANSACTION
...Execute some sql statements here
COMMIT TRANSACTION (When every thing goes well)
ROLLBACK TRANSACTION (When something goes wrong)
Please tell me what is the best way to do this i know there is a ##TranCount variable but dont know its exact purpose.
Thanks.
Begin Transaction
Alter Table dbo.MyTable
Add Col1 varchar(50)
If ##Error = 0
Begin
Commit Transaction
End
Else
Begin
Rollback Transaction
End
##Error gets reset after each SQL Statement so you must check it immediately after each statement has been executed to check for any errors.

Raising errors in After Triggers Sql Server 2005

If I raise an error in an AFTER UPDATE trigger in Sql Server 2005, will that cause the update which caused the trigger to be fired to roll back, even if the statement was not executed within a transaction?
Thanks.
No, you have to rollback transaction by calling ROLLBACK TRAN:
CREATE TRIGGER trg_au_table
ON dbo.table
AFTER UPDATE
AS
BEGIN
ROLLBACK TRAN
END
GO
This example will prevent from updating any record.
This:
CREATE TRIGGER trg_au_table
ON dbo.table
AFTER UPDATE
AS
BEGIN
RAISERROR('This is a test', 16, 1)
END
GO
will only raise the error but the change will be made in the table.