I have to insert and delete from multiple tables and I wanted to do all these in one single stored procedure so can I have the multiple transactions blocks as below and what would be the best way to handle errors in each transaction.Please advise
BEGIN TRANSACTION [TRANS1]
BEGIN TRY
Insert into ArchiveTable select * from Completed (nolock)
delete from Completed(nolock) where convert(date,LastModified,101) > getdate()
COMMIT TRANSACTION [TRANS1]
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION [TRANS1]
PRINT ERROR_MESSAGE()
END CATCH
BEGIN TRANSACTION [TRANS2]
BEGIN TRY
Insert into ArchiveTable2 select * from New (nolock)
delete from New (nolock) where convert(date,LastModified,101) > getdate()
COMMIT TRANSACTION [TRANS2]
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION [TRANS2]
PRINT ERROR_MESSAGE()
END CATCH
Related
I Have sample procedure .
CREATE PROCEDURE `sample_procedure `
(
IN IDIn bigint(20),
IN MainIDIn bigint(20),
IN NameIn varchar(20)
)
READS SQL DATA
DETERMINISTIC
BEGIN
INSERT INTO tbl_DEPT
(
ID,
Name)
Select 1,'Mohan';
IF NOT EXISTS (SELECT ID FROM tbl_emp te WHERE te.ID = IDIn) THEN
INSERT INTO tbl_emp
(
MainID,
Name)
VALUES (MainIDIn,
NameIn);
ELSE
IF EXISTS (SELECT ID FROM tbl_emp te WHERE te.ID = IDIn) THEN
UPDATE tbl_emp
set
MainID =MainIDIn,
name = NameIn
WHERE te.ID= IDIn;
END IF;
END IF;
END
Call sample_procedure(1,2,Sampl123)
I'm just sending some irrelevant Data into the Procedure so that procedure gets failed . But how we need to implement roll back means it should come to the starting state with out Inserting Records into the tbl_DEPT also.
IN T-SQL we will have
BEGIN
SET NOCOUNT ON
BEGIN TRANSACTION
BEGIN TRY
SET #OUT = "success";
COMMIT TRANSACTION
END TRY
BEGIN CATCH
set #out = 'not success';
ROLLBACK TRANSACTION
END CATCH
END
this kind of TRY CATCH blocks and to capture Error
"ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity"
In the same way in MYSQL I'm looking for TRY CATCH and ROLL BACK Mechanism .
IF Procedure fails it should ROLL BACK and Not to load in any of the table .
Can any one Suggest me in MYSQL.
Mysql does not use try/catch. If uses handlers, e.g. the EXIT handler that will terminate the execution of the SP:
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
-- other logic
END;
There are other type of handlers as well.
I get an error
Custom error message. Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0. Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0.
My SQL Code is following
Procedure 1
CREATE PROCEDURE [dbo].[spProcedure1]
#Id int
WITH EXECUTE AS OWNER
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION
EXEC spProcedure2 #Id
-- Code ommited, Next procedures execution
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0
ROLLBACK TRANSACTION
-- Code ommited, saving error to Log table
RAISERROR(#errorMessage, #errorSeverity, #errorState);
END CATCH
END
Procedure 2
CREATE PROCEDURE [dbo].[spProcedure2]
#Id int
WITH EXECUTE AS OWNER
BEGIN
BEGIN TRY
-- Check if record exists
IF NOT EXISTS(SELECT * FROM dbo.Table t WHERE t.Id = #Id)
BEGIN
-- stop procedure due to user error
RAISERROR('Custom error message.',16,1)
RETURN
END
-- Code ommited, DML operation
END TRY
BEGIN CATCH
-- Code ommited, saving error to Log table
RAISERROR(#errorMessage, #errorSeverity, #errorState);
END CATCH
END
I am not sure how to handle transaction in the Procedure 2 to obey this error ?
Hi i have one sp where i used try catch with transaction. below is the code
USE [Securtimeweb2.1]
GO
/****** Object: StoredProcedure [dbo].[UpdateCompany] Script Date: 7/6/2015 12:14:27 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[UpdateCompany]
(
#CompanyCode varchar(max),
#NewCompCode varchar(max)=null,
#TRANSVAL VARCHAR(MAX)
)
as
BEGIN
BEGIN TRY
BEGIN TRAN #TRANSVAL
update BranchMaster set CompanyCode=#NewCompCode Where CompanyCode=#CompanyCode
COMMIT TRAN #TRANSVAL
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() AS strMessage
ROLLBACK TRAN #TRANSVAL
END CATCH
END
then i use this code to run this sp in another query window
EXEC UpdateCompany '002','003','TRAN1'
so after using this in one another query window i am trying to rollback the transaction which is
DECLARE #TRAN VARCHAR(MAX)='TRAN1'
BEGIN TRAN #TRAN
ROLLBACK TRAN #TRAN
so here we can see i given some name for the transaction and trying to rollback with the same name but it's not getting rollback.
Am i doing anything wrong here??
Use This Links To Know How Transaction Works
http://www.sqlservercurry.com/2011/01/rollback-transaction-in-sql-server.html
I use following standard, maybe it can help :
BEGIN TRAN
BEGIN TRY
--YOUR SQL STATEMENTS
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() AS [STATUS]
ROLLBACK TRAN
END CATCH
IF ##TRANCOUNT > 0
BEGIN
COMMIT TRAN
SELECT 'SUCCESS' AS [STATUS]
END
I created a stored procedure that has 9 inserts in summarized tables and the last statement is a delete.
This procedure takes around 9 minutes to execute for each given date, and one thing that I noticed is that if an error occurs and the first 3 inserts executed, it keeps the inserted data. To handle this, I created a begin try and begin transaction and a test that I did was to start the procedure using SSMS and after it started, I cancelled the command but the transaction was kept. How can I avoid this?
the procedure body is very simple... something like:
insert into...
insert into...
insert into...
insert into...
insert into...
insert into...
insert into...
insert into...
insert into...
insert into...
delete from....
thanks
Two things:
1) The basic syntax is:
BEGIN TRY
BEGIN TRAN
INSERT...
DELETE...
COMMIT TRAN
END TRY
BEGIN CATCH
IF (##TRANCOUNT > 0)
BEGIN
ROLLBACK TRAN
END
DECLARE #ErrorMessage NVARCHAR(4000)
SET #ErrorMessage = 'Line ' + CONVERT(VARCHAR(20), ERROR_LINE()) + ': '
+ ERROR_MESSAGE()
RAISERROR(#SQLErrString, 16, 1)
END CATCH
2) If you cancel a batch in process, you might need to run the ROLLBACK TRAN manually. You can test if you need to do this by doing a SELECT ##TRANCOUNT and if it is > 0 then call ROLLBACK TRAN.
I have a huge script for creating tables and porting data from one server. So this sceipt basically has -
Create statements for tables.
Insert for porting the data to these newly created tables.
Create statements for stored procedures.
So I have this code but it does not work basically ##ERROR is always zero I think..
BEGIN TRANSACTION
--CREATES
--INSERTS
--STORED PROCEDURES CREATES
-- ON ERROR ROLLBACK ELSE COMMIT THE TRANSACTION
IF ##ERROR != 0
BEGIN
PRINT ##ERROR
PRINT 'ERROR IN SCRIPT'
ROLLBACK TRANSACTION
RETURN
END
ELSE
BEGIN
COMMIT TRANSACTION
PRINT 'COMMITTED SUCCESSFULLY'
END
GO
Can anyone help me write a transaction which will basically rollback on error and commit if everything is fine..Can I use RaiseError somehow here..
Don't use ##ERROR, use BEGIN TRY/BEGIN CATCH instead. See this article: Exception handling and nested transactions for a sample procedure:
create procedure [usp_my_procedure_name]
as
begin
set nocount on;
declare #trancount int;
set #trancount = ##trancount;
begin try
if #trancount = 0
begin transaction
else
save transaction usp_my_procedure_name;
-- Do the actual work here
lbexit:
if #trancount = 0
commit;
end try
begin catch
declare #error int, #message varchar(4000), #xstate int;
select #error = ERROR_NUMBER(), #message = ERROR_MESSAGE(), #xstate = XACT_STATE();
if #xstate = -1
rollback;
if #xstate = 1 and #trancount = 0
rollback
if #xstate = 1 and #trancount > 0
rollback transaction usp_my_procedure_name;
raiserror ('usp_my_procedure_name: %d: %s', 16, 1, #error, #message) ;
return;
end catch
end
As per http://msdn.microsoft.com/en-us/library/ms188790.aspx
##ERROR: Returns the error number for the last Transact-SQL statement executed.
You will have to check after each statement in order to perform the rollback and return.
Commit can be at the end.
HTH
Avoid direct references to '##ERROR'.
It's a flighty little thing that can be lost.
Declare #ErrorCode int;
... perform stuff ...
Set #ErrorCode = ##ERROR;
... other stuff ...
if #ErrorCode ......