Receiving an error: The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION in SQL Script - sql

Was trying to perform an update to a database for an application, and then SQL server threw me a Commit has no corresponding being transaction. It was kind enough to point me to the procedure but I cannot seem to find what the issue is.
This is my code:
ALTER PROCEDURE [dbo].[sp_tblUser_Update] #UserID INTEGER,
#UserName NVARCHAR(20),
#Password NVARCHAR(10),
#Yard NVARCHAR(50),
#NewRole NVARCHAR(50),
#FullName NVARCHAR(50),
#Email NVARCHAR(50),
#BCConEmails BIT,
#CrewStatusReadOnly BIT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
UPDATE tblUser
SET UserName = #UserName,
UserPassword = #Password,
Yard = #Yard,
Fullname = #FullName,
EmailAddress = #Email,
NewRole = #NewRole,
BCConEmails = #BCConEmails,
CrewStatusReadOnly = #CrewStatusReadOnly
WHERE ( UserID = #UserID )
END
GO
COMMIT

You don't need the COMMIT line as the END in your code is what terminates the previous BEGIN. If you want to add a transaction you should put a BEGIN TRANSACTION before the update statement and move the COMMIT before the END

begin tran
delete from Customerages
where Age=25
commit;
begin tran
delete from Customerages
where Age=25
rollback;

Related

Update followed by insert in a stored procedure

I'm not sure that's the correct way making an update followed by insert in a stored procedure.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[io_sp_admin_add_emp]
#id BIGINT,
#lastName VARCHAR(20),
#firstName VARCHAR(20)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION [TranAddEmp]
DECLARE #identity BIGINT = 0
INSERT INTO empTable(LastName, FirstName, hash_id)
VALUES (#lastName, #firstName,
HashBytes('SHA2_256', CAST(#id AS VARBINARY(50))))
SELECT #identity = ##identity
UPDATE empTable
SET rowId = incId -- both are columns in empTable
WHERE hash_id = #identity
COMMIT TRANSACTION [TranAddEmp]
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION [TranAddEmp]
END CATCH
END
A simple change to your current code can give you what you're looking for.
Instead of messing around with ##Identity, which is almost never the right thing to do, you compute the hash of the #Id value once, store it in a local variable, and use it for both the insert statement and the where clause of the update statement - That is, assuming the HashId column is unique.
That being said, I'm not sure why you need the rowId column as well as the incId column - unless one of them is designed to change it's value through an update statement in the lifetime of the row - you are simply keeping redundant data.
Here's an improved version of your stored procedure:
CRETAE PROCEDURE [dbo].[io_sp_admin_add_emp]
#id BIGINT,
#lastName varchar(20),
#firstName varchar(20)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRANSACTION [TranAddEmp]
-- Compute the hash once, store in a local variable
DECLARE #HashId varbinary(8000) = HashBytes('SHA2_256', cast(#id as varbinary(50)))
INSERT INTO empTable(
LastName,
FirstName,
hash_id
)
VALUES(
#lastName,
#firstName,
#HashId
)
UPDATE empTable
SET rowId = incId
WHERE hash_id = #HashId
COMMIT TRANSACTION [TranAddEmp]
END TRY
BEGIN CATCH
-- make sure transaction has started and is not commited
IF ##TRANCOUNT > 0
ROLLBACK TRANSACTION [TranAddEmp]
END CATCH
END
There is a great keyword OUTPUT. As MSDN says:
Returns information from, or expressions based on, each row affected
by an INSERT, UPDATE, DELETE, or MERGE statement. These results can be
returned to the processing application for use in such things as
confirmation messages, archiving, and other such application
requirements. The results can also be inserted into a table or table
variable. Additionally, you can capture the results of an OUTPUT
clause in a nested INSERT, UPDATE, DELETE, or MERGE statement, and
insert those results into a target table or view.
You can insert your inserted id's into table through OUTPUT keyword. For example:
DECLARE #InsertedIDs TABLE (ID varbinary(8000))
INSERT INTO empTable(
LastName,
FirstName,
hash_id
)
OUTPUT HashBytes('SHA2_256', cast(INSERTED.ID as varbinary(50))) INTO #InsertedIDs(ID)
VALUES(
#lastName,
#firstName,
HashBytes('SHA2_256', cast(#id as varbinary(50)))
)
UPDATE empTable
Set rowId = incId -- both are columns in empTable
WHERE hash_id in (SELECT ID IN #InsertedIDs)

Execute a stored procedure from another, and return two variables

I have a stored procedure called clients with 3 parameters: the first one for user input, and the last two are OUTPUT parameters.
This is the code:
CREATE PROCEDURE clients
(#name NVARCHAR(100),
#id_client int OUTPUT,
#messg varchar(1) OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRAN
IF NOT EXISTS (SELECT name FROM client WHERE name = #name)
BEGIN
INSERT INTO client(name) VALUES (#name);
SET #id_client = SCOPE_IDENTITY();
SET #messg = 'o'
COMMIT TRAN
END
ELSE
BEGIN
SELECT #id_client = id_client
FROM client
WHERE name = #name;
SET #messg = 'o'
COMMIT TRAN
END
END TRY
BEGIN CATCH
SET #messg = 'e'
ROLLBACK TRAN
END CATCH
END
I need to call this stored procedure from another the second one is called updateS, and I'm trying the following:
CREATE PROCEDURE updateS
(#clientname VARCHAR(100))
AS
BEGIN
SET NOCOUNT ON;
DECLARE #id INT;
DECLARE #msg VARCHAR(1);
EXEC clients #clientname, #id, #msg; --Problem here to retrieve the id
END
This stored procedure has a parameter for the name of the client, but I need to retrieve the id of the client, but it doesn't work as I'm trying.
Basically I need to get the id and use it in the second stored procedure.
Any question post on comments.
You need to specify OUTPUT when you execute the stored procedure as well as when you define it:
EXEC clients #clientname, #id OUTPUT, #msg OUTPUT;
Did you miss the output keyword while passing the parameter to the stored procedure? Moreover, I would change the clients stored procedure and make the parameter as char(1) rather like #messg char(1) OUTPUT

stored procedure sql server 2008

I am working on a project and am using stored procedure. I'm getting this error:
Line: 939
Error: Sys.WebForms.PageRequestManagerServerErrorException: Invalid object name 'IT_Assets'.
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.
Please find below my stored procedure code:
alter PROCEDURE [ITAssets_sp_IT_Assets]
-- Add the parameters for the stored procedure here
(#Mode varchar(12)='ADD',
#ID integer , #AssetCode nvarchar(20)=null, #Description nvarchar(70)=null,
#Site nvarchar(10)=null)
AS
Begin
IF #Mode='ADD'
Begin
Begin Tran
INSERT INTO [IT_Assets]
([ID]
,[AssetCode]
,[Description]
,[Site])
values
(#ID, #AssetCode, #Description, #Site
)
If ##ERROR <> 0
ROLLBACK TRAN
Else
COMMIT TRAN
Select #ID
End
ELSE
Begin
Begin Tran
UPDATE [IT_Assets]
SET
AssetCode = #AssetCode, Description = #Description, Site = #Site
WHERE ID = #ID
If ##ERROR <> 0
ROLLBACK TRAN
Else
COMMIT TRAN
Select #ID
End
End
I didn't understand the error and I don't know exactly where is the problem? Would someone please help me in sloving this problem?
From the error Invalid object name 'IT_Assets' I believe that the table/view 'IT_Assets' is present in a diferent database than the stored procedure (assuming that the object exist and you are using the correct name).
Then you need to fully quaify it wih Db name like
UPDATE [DB_NAME].[dbo].[IT_Assets] (assuming `dbo` is the owner)
Try using your database name at top of procedure using use statement like
use [DB_NAME]
GO
alter PROCEDURE [ITAssets_sp_IT_Assets]
-- Add the parameters for the stored procedure here
(#Mode varchar(12)='ADD',
...
Also change you transaction handling using TRY .. CATCH consruct like below
Begin Tran
BEGIN TRY
INSERT INTO [IT_Assets]
([ID]
,[AssetCode]
,[Description]
,[Site])
values
(#ID, #AssetCode, #Description, #Site);
COMMIT TRAN;
END TRY
BEGIN CATCH
ROLLBACK TRAN ;
END CATCH

Set output parameter when commit transaction fails

I need to roll back the transaction whenever any one of the query fails. If all the transaction is OK, it has to set the output parameter.
So far I have done this.
create PROCEDURE [dbo].[sp_InsertAll]
-- Add the parameters for the stored procedure here
#WO_Type varchar(25),
#WO_Operation varchar(25),
#WO_Source varchar(25),
#RETVAL BIT OUT
AS
BEGIN
SET NOCOUNT ON;
SET #RETVAL = 0
SET XACT_ABORT ON
BEGIN TRAN;
INSERT INTO tblTabl1(WO_Type , WO_Operation , WO_Source )
VALUES (#WO_Type, #WO_Operation, #WO_Source, )
IF #UPDATESOURCE = 1
BEGIN
UPDATE tblT2
SET SM_SaddleStatus = #SOURCESTATUS
WHERE SM_SaddleID = #WO_SourceID
END
IF #UPDATEDESTINATION = 1
BEGIN
UPDATE tblT3
SET SM_SaddleStatus = #DESTINATIONSTATUS
WHERE SM_SaddleID = #WO_DestinationID
END
SET #RETVAL = 1
COMMIT TRAN;
END
Is this the right way to return value? Is there any problem with the method. So far it is working fine for me. Before moving to production I need to cross check.
This is what I'd suggest, using a TSQL Try Catch block to roll back the transaction and give you a different return value:
create PROCEDURE [dbo].[sp_InsertAll]
-- Add the parameters for the stored procedure here
#WO_Type varchar(25),
#WO_Operation varchar(25),
#WO_Source varchar(25),
--#RETVAL BIT OUT
AS
BEGIN
SET NOCOUNT ON;
SET #RETVAL = 0
SET XACT_ABORT ON
BEGIN TRAN;
BEGIN TRY
INSERT INTO tblTabl1(WO_Type , WO_Operation , WO_Source )
VALUES (#WO_Type, #WO_Operation, #WO_Source, )
IF #UPDATESOURCE = 1
BEGIN
UPDATE tblT2
SET SM_SaddleStatus = #SOURCESTATUS
WHERE SM_SaddleID = #WO_SourceID
END
IF #UPDATEDESTINATION = 1
BEGIN
UPDATE tblT3
SET SM_SaddleStatus = #DESTINATIONSTATUS
WHERE SM_SaddleID = #WO_DestinationID
END
return 0
COMMIT TRAN;
END TRY
BEGIN CATCH
rollback Tran;
return -1
END CATCH
END

Getting an error in sql

I am getting this error:
Procedure or function 'NewEmployee' expects parameter '#LastName', which was not supplied
This is what I have:
CREATE PROCEDURE NewEmployee1 (
#LastName nvarchar(75)
,#FirstName nvarchar(50)
,#HireDate datetime
,#Birthdate datetime
,#Title nvarchar(30))
WITH EXECUTE AS CALLER
AS
BEGIN
Set NOCOUNT ON;
Begin Try
Begin Transaction;
INSERT INTO Employees (LastName,FirstName,HireDate,BirthDate,Title)
VALUES (#LastName, #FirstName, #HireDate,#Birthdate,#Title)
COMMIT TRANSACTION;
End Try
Begin Catch
--Rollback any active or uncommitable transactions before
--inserting information in the errorLog
If ##Trancount > 0
Begin
Rollback Transaction;
End
Execute NewEmployee1 ;
End Catch;
End;
Exec NewEmployee
#LastName = 'Halpert',
#FirstName = 'Jim',
#HireDate = '11/14/2011',
#BirthDate = '04/02/1971',
#Title = 'Sales';
Should I have it like #lastName nvarchar(75) = Null?
You have the line Execute NewEmployee1 ; which attempts to execute the stored procedure with no parameters.
If you want default values assigned to parameters, you need to do as you suggested...
CREATE PROCEDURE NewEmployee1 (
#LastName nvarchar(75) = NULL
,#FirstName nvarchar(50) = NULL
,#HireDate datetime = NULL
,#Birthdate datetime = NULL
,#Title nvarchar(30) = NULL
)
Or replacing the NULLs with any appropriate default value.
You define the procedure as NewEmployee1, but then you call NewEmployee.
EDIT:
I think that calling Execute NewEmployee1 ; in the CATCH statement could potentially cause an infinite loop if there were some problem calling the stored procedure with the default values... Are you sure you want to call the SP again in the CATCH?
I see
CREATE PROCEDURE **NewEmployee1**
while you later on call it using
Exec NewEmployee
withiout the 1 at the end of the name.
Probably you have another procedure NewEmployee, which does not have a param #LastName.