Transaction count after EXECUTE indicates mismatching number of BEGIN and COMMIT statements - sql

When I execute the below stored procedure I get this error:
System.Data.SqlClient.SqlException: Transaction count after EXECUTE
indicates a mismatching number of BEGIN and COMMIT statements.
Previous count = 0, current count = 1.
Code:
create procedure [dbo].[sp_crm_diler_master]
(
#Fullname varchar(100),
#Email varchar(50),
#Mobile varchar(12),
#qualification varchar(50),
#presentaddress varchar(250),
#permanentaddress varchar(250),
#location varchar(50),
#skills varchar(100),
#Dob varchar(15),
#myphoto varbinary(Max),
#uniqueid varchar(25),
#Message varchar(150) output
)
AS
BEGIN
if not exists (select emailid,phone from crm_masterdata where emailid=#Email And phone=#Mobile)
begin
begin transaction
declare #small smalldatetime = (select CAST(#Dob as smalldatetime))
declare #todaydate datetime=(select getdate())
insert into crm_masterdata(uniqueid,fullname,phone,dob,photo,emailid,qualification,location,present_address,permanent_address,skillsets,datasource,entrydate,active)
values(#uniqueid,#Fullname,#Mobile,#small,#myphoto,#Email,#qualification,#location,#presentaddress,#permanentaddress,#skills,'reception',#todaydate,1)
Set #Message=' Registration Successfull,Please Login'
end
else
begin
set #Message='This User Already Registered'
end
end
Where is my error?

create procedure [dbo].[sp_crm_diler_master]
(
#Fullname varchar(100),
#Email varchar(50),
#Mobile varchar(12),
#qualification varchar(50),
#presentaddress varchar(250),
#permanentaddress varchar(250),
#location varchar(50),
#skills varchar(100),
#Dob varchar(15),
#myphoto varbinary(Max),
#uniqueid varchar(25),
#Message varchar(150) output
)
AS
BEGIN
SET NOCOUNT ON;
declare #small smalldatetime = (select CAST(#Dob as smalldatetime));
declare #todaydate datetime=getdate();
declare #Error INT;
BEGIN TRANSACTION; --<-- You need to commit it
IF not exists (select 1 from crm_masterdata where emailid=#Email And phone=#Mobile)
BEGIN
insert into crm_masterdata(uniqueid,fullname,phone,dob,photo,emailid
,qualification,location,present_address,permanent_address,skillsets,datasource,entrydate,active)
values(#uniqueid,#Fullname,#Mobile,#small,#myphoto,#Email,#qualification
,#location,#presentaddress,#permanentaddress,#skills,'reception',#todaydate,1)
SET #Error = ##ERROR;
Set #Message =' Registration Successfull,Please Login'
END
ELSE
BEGIN
SET #Message='This User Already Registered'
END
IF (#Error = 0)
COMMIT TRANSACTION; --<-- Commit tran
ELSE
ROLLBACK TRANSACTION;
END

I don't see a COMMIT TRANSACTION to match your BEGIN TRANSACTION.

Related

SQL Server stored procedure: verify CRUD operation success/failure using output variable

I am trying to create a SQL Server stored procedure to handle updates to a table using some dynamic SQL. The table name required for the update is stored in a table that correlates a table id to a category id. Once the table name is retrieved and the table id is not null, I update the table using a dynamic SQL query as shown below:
CREATE PROCEDURE [dbo].[SP_EBS_CustomForms_SetCategoryData]
(#flag int output,
#cat_id int,
#sort int,
#value varchar(50),
#active int,
#enum int)
AS
BEGIN
DECLARE #tbl as varchar(50)
DECLARE #tbl_id as int
DECLARE #sql nvarchar(max)
BEGIN TRY
SET #tbl_id = (SELECT [tbl_id]
FROM [demodata].[dbo].[ebscustomforms_cattable]
WHERE cat_id = #cat_id)
IF #tbl_id IS NOT NULL
BEGIN
SET #tbl = (SELECT table_name
FROM ebscustomforms_enumtable
WHERE tbl_id = #tbl_id)
SET #sql = 'UPDATE ' + #tbl + ' SET [sort_order] = #sort, [value] = #value, [active] = #active WHERE [enum_id] = #enum'
EXECUTE sp_executesql #sql, N'#sort int, #value varchar(50), #active int, #enum int', #sort, #value, #active, #enum
SET #flag = 0
RETURN #flag
END
END TRY
BEGIN CATCH
IF ##ERROR <> 0
BEGIN
SET #flag = 1;
RETURN #flag
END
END CATCH
END
I want this stored procedure to return an int value indicating whether the stored procedure was successful (0) or failed (1) updating the table.
Points of error are as follows:
#tbl_id variable is null
#tbl is either null or an empty varchar
The table to be updated does not have a record where [enum_id] = #enum
I have noticed that when I try to update a record that does not exist, the procedure seems to return as successful i.e. #flag = 0. However, I would imagine that an error should be thrown because the record does not exist.

RAISERROR Dosn't Work Inside CATCH With ROLLBACK TRANSACTION

I created a Stored Procedure to Insert Into 2 Table With Transaction to make sure That Both Inserts Done and I Used TRY and CATCH to Handle The Errors .. The Problem Is In The Catch Statement I Put ROLLBACK TRANS and RAISERROR The RoLLBACK Works But The Procedure Dose not RAISERROR
Here is The Code
ALTER PROC SP_InsertPlot
#PlotName nvarchar(50),
#GrossArea int,
#SectorName Nvarchar(50),
#PlotYear int,
#OwnerName Nvarchar(50),
#Remarks text,
#NumberOfPlants INT,
#NetArea INT,
#Category Nvarchar(50),
#Type Nvarchar(50),
#Variety Nvarchar(50),
#RootStock Nvarchar(50),
#PlantDistance Decimal(18,2)
AS
BEGIN
DECLARE #PlotID INT
SET #PlotID = (SELECT ISNULL(MAX(PlotID),0) FROM Plots) + 1
DECLARE #SectorID INT
SET #SectorID = (SELECT SectorID FROM Sectors WHERE SectorName = #SectorName)
DECLARE #OwnerID INT
SET #OwnerID = ( SELECT OwnerID FROM Owners WHERE OwnerName = #OwnerName)
DECLARE #CategoryID INT
SET #CategoryID = (SELECT CategoryID FROM Categories WHERE CategoryName = #Category)
DECLARE #TypeID INT
SET #TypeID = (SELECT TypeID FROM Types WHERE TypeName = #Type)
DECLARE #VarietyID INT
SET #VarietyID = (SELECT VarietyID FROM Varieties WHERE VarietyName = #Variety)
DECLARE #RootStockID INT
SET #RootStockID = (SELECT RootStockID FROM RootStocks WHERE RootStockName = #RootStock)
DECLARE #PlotDescID INT
SET #PlotDescID = (SELECT ISNULL(MAX(PlotDescID),0) FROM PlotDescriptionByYear) + 1
BEGIN TRY
SET XACT_ABORT ON
SET NOCOUNT ON
IF(SELECT Count(*) FROM Plots WHERE PlotName = #PlotName) = 0
BEGIN
BEGIN TRANSACTION
INSERT INTO Plots (PlotID,PlotName,GrossArea,SectorID,PlantYear,OnwerID,Remarks)
VALUES(#PlotID,#PlotName,#GrossArea,#SectorID,#PlotYear,#OwnerID,#Remarks)
INSERT INTO PlotDescriptionByYear (PlotDescID, PlantYear, NumberOfPlants,PlotID,NetArea,CategoryID,TypeID,VarietyID,RootStockID,PlantDistance)
VALUES(#PlotDescID,YEAR(GETDATE()),#NumberOfPlants,#PlotID -1,#NetArea,#CategoryID,#TypeID,#VarietyID,#RootStockID,#PlantDistance)
COMMIT TRANSACTION
END
END TRY
BEGIN CATCH
IF(XACT_STATE())= -1
BEGIN
ROLLBACK TRANSACTION
RAISERROR('This Plot Is Already Exists !!',11,1)
END
END CATCH
END
By the way i tried to change the Severity and I tried ##TRANCOUNT instead of XACT_STATE and the Same Problem Happens Which is When I Exec Proc and Pass an Existing Data To The Parameters The Transaction Roll back and did not rise the error
Change IF(XACT_STATE())= -1 to IF(XACT_STATE()) <> 0 and your problem will be done.

Procedure or function has too many arguments SQL server

I getting this error while executing the stored procedure in SQL Server:
Msg 8144, Level 16, State 2, Procedure sp_adduser, Line 2
Procedure or function sp_adduser has too many arguments specified.
The weird thing is that the number of parameters is the same as declared in the procedure, even when I execute it while right-click on the procedure and press execute, input the parameters from the fields and still the same error.
This is the code of the procedure and the exec:
create procedure [dbo].[sp_addUser]
(
#userID nvarchar(50),
#pw nvarchar(50),
#fName nvarchar(50),
#lname nvarchar(50),
#email nvarchar(150),
#address nvarchar(150),
#city int,
#country int,
#phone nvarchar(50),
#gender nvarchar(10),
#dob date,
#photo nvarchar(150),
#secq int,
#secAnswer nvarchar(150),
#completed int output)
as
declare #found int
/*
usertype:
0 - Administrator
1 - User
*/
begin
begin
select #found=count(*) from registration r
where REPLACE(r.firstname,' ','')=REPLACE(#fName,' ','')
and REPLACE(r.lastname,' ','')=REPLACE(#lname,' ','')
and r.dateofbirth=#dob;
end
begin
if #found=0
begin
begin
insert into Login values(#userID,#pw,0,1);
end
begin
insert into registration values(
#userID,#fName,#lname,#email,
#address,#city,#country,#phone,
#gender,#dob,#photo,#secq,#secAnswer
)
end
begin
set #completed=1;
end
end
else set #completed=0
end
return #completed
end
And here is the exec:
DECLARE #return_value int,
#completed int
SELECT #completed = 0
EXEC #return_value = [dbo].[sp_addUser]
#userID = N'a',
#pw = N'a',
#fName = N'a',
#lname = N'a',
#email = N'a',
#address = N'a',
#city = 1,
#country = 1,
#phone = N'a',
#gender = N'a',
#dob = '01/01/2000',
#photo = N'a',
#secq = 1,
#secAnswer = N'a',
#completed = #completed OUTPUT
SELECT #completed as N'#completed'
SELECT 'Return Value' = #return_value
Thanks in advance!
sp_adduser is a procedure which is built-in to SQL Server - see https://msdn.microsoft.com/en-us/library/ms181422.aspx
Don't use the sp_ prefix for your own stored procedures, maybe call it proc_adduser instead, I think that will work
You are actually calling the system stored procedure sp_adduser. The "sp_" prefix is special and has its own rules on resolution, so using it is recommended against. If you want to use your own prefix, whatever you do, don't use "sp_".
Per #marc_s, even if your stored procedure doesn't clash with an existing system stored procedure, you will still get a noticeable performance hit due to cache misses.

execute stored procedure based on condition

i tried to insert data in database using stored procedure but according to some condition. for example if data is already exists in database the the stored procedure should not be executed.
i am doing the following code but it return 0 every time rather then i want. What can i do
ALTER PROCEDURE dbo.SaveUser
(
#cid int,
#firstname varchar(20),
#lastname varchar(20),
#dob datetime,
#gender varchar(20),
#add varchar(100),
#email varchar(40),
#quali varchar(20),
#yop varchar(15),
#exp varchar(10),
#pass varchar(20)
)
AS
declare #result int
if EXISTS( select Email_ID from Registration where Email_ID=#email )
begin
set #result=4;
return #result;
end
else
begin
insert into Registration values(#cid, #firstname, #lastname, #dob, #gender, #add, #email, #quali, #yop, #exp, #pass );
set #result =0;
return #result;
end
You can simply proceed as follows;
ALTER PROCEDURE dbo.SaveUser
(
#cid int,
#firstname varchar(20),
#lastname varchar(20),
#dob datetime,
#gender varchar(20),
#add varchar(100),
#email varchar(40),
#quali varchar(20),
#yop varchar(15),
#exp varchar(10),
#pass varchar(20)
)
AS
BEGIN
DECLARE #return int
if NOT EXISTS(select Email_ID from Registration where Email_ID=#email)
insert into Registration values(#cid, #firstname, #lastname,
#dob, #gender, #add, #email,
#quali, #yop, #exp, #pass )
If (##ERROR <> 0)
Begin
Set #return = 4
Else
Set #return = 0
End
Return #return
END
You can use raiseerror event for this scenario
if EXISTS( select Email_ID from Registration where Email_ID=#email )
begin
RAISERROR(N'Email id already exist.', 10, 2,'')
end
Here 10 is severity level and according to severity level sql server identified as info meassage or exception. For more information
RaiseError
Database Engine Severity Levels
Try this one -
ALTER PROCEDURE dbo.SaveUser
(
#cid INT,
#firstname VARCHAR(20),
#lastname VARCHAR(20),
#dob DATETIME,
#gender VARCHAR(20),
#add VARCHAR(100),
#email VARCHAR(40),
#quali VARCHAR(20),
#yop VARCHAR(15),
#exp VARCHAR(10),
#pass VARCHAR(20)
)
AS BEGIN
IF NOT EXISTS(
SELECT 1
FROM dbo.Registration
WHERE Email_ID = #email
) BEGIN
INSERT INTO dbo.Registration
SELECT #cid, #firstname, #lastname, #dob, #gender, #add, #email, #quali, #yop, #exp, #pass
RETURN 0;
END
RETURN 4;
END

SQL call a SP from another SP

Can I please have some help with the syntax of a SP in SQL.
Here is my code:
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10)
)
AS
BEGIN
return #ID + #Description
END
CREATE PROCEDURE usp_InsertValue
(
#ID VARCHAR(10),
#FirstName VARCHAR(50),
#LastName VARCHAR(50),
#Description VARCHAR(10),
#Comment VARCHAR(max)
)
AS
BEGIN
Declare #v_Value VARCHAR(15)
Set #v_Value = usp_GetValue(#ID, #Description)
END
In the usp_InsertValue SP, I am wanting to declare and set a variable. Once the variable has been declared, I then wish to call another SP with parameters to set the value of the declared variable.
I am not sure of the syntax. May I please have some help?
UPDATE
I have updated my above code using your function. How do I Set the #v_Value from the usp_GetValue function.
I am getting this error:
'usp_GetValue' is not a recognized built-in function name.
UPDATE2
Here is my full code:
CREATE PROCEDURE usp_PersonCategoryLookupTesting
(
#ID VARCHAR(10),
#Description VARCHAR(10),
#res VARCHAR(10) OUTPUT
)
AS
BEGIN
return #ID + #Description
END
CREATE PROCEDURE usp_InsertPersonTesting
(
#IDTest VARCHAR(10),
#FirstName VARCHAR(50),
#LastName VARCHAR(50),
#AddressLine1 VARCHAR(50),
#AddressLine2 VARCHAR(50),
#AddressLine3 VARCHAR(50),
#MobilePhone VARCHAR(20),
#HomePhone VARCHAR(20),
#Description VARCHAR(10),
#Comment VARCHAR(max)
)
AS
BEGIN
Declare #PersonCategory VARCHAR(15)
EXEC usp_PersonCategoryLookupTest #ID, #Description, #PersonCategory
INSERT INTO Person(FirstName, LastName, AddressLine1, AddressLine2, AddressLine3, MobilePhone, HomePhone, DateModified, PersonCategory, Comment)
VALUES (#FirstName, #LastName, #AddressLine1, #AddressLine2, #AddressLine3, #MobilePhone, #HomePhone, GETDATE (), #PersonCategory, #Comment)
END
I am getting this error in my application that is calling the SQL code:
Conversion failed when converting the varchar value '123Client' to data type int.
I am using the values "123" and "Client" for #IDTest and #Description.
I think output parameters should be the proper way:
See this post:
stored procedure returns varchar
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10),
#res VARCHAR(10) OUTPUT
)
AS
BEGIN
return #ID + #Description
END
CREATE PROCEDURE usp_InsertValue
(
#ID VARCHAR(10),
#FirstName VARCHAR(50),
#LastName VARCHAR(50),
#Description VARCHAR(10),
#Comment VARCHAR(max)
)
AS
BEGIN
Declare #v_Value VARCHAR(15)
EXEC usp_GetValue #ID, #Description, #v_Value
-- use #v_Value here...
END
You can only use a function like that, not stored procedure. Stored Procedures only return integer values.
For SP, you need to create out parameters to retrieve the values. For this scenario, it is better to create a function
CREATE FUNCTION usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10),
)
RETURNS VARCHAR(50)
AS
BEGIN
return #ID + #Description
END
Then call it:
SET #v_value = dbo.usp_GetValue('John','Doe') --output: John Doe
If you insist you want a SP, which is not proper for this, there are 2 ways
1) An out parameter
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10),
#Result varchar(20) OUTPUT
)
AS
BEGIN
SET #Result = #ID + #Description
END
Then call it:
Declare #v_Value VARCHAR(15)
Set #v_Value = EXEC usp_GetValue #ID, #Description, #v_Value OUTPUT
2) Select from it
CREATE PROCEDURE usp_GetValue
(
#ID VARCHAR(10),
#Description VARCHAR(10)
)
AS
BEGIN
SELECT #ID + #Description
END
Use it like this:
declare #tempresult as table(v_value as varchar(15))
INSERT INTO #tempresult
EXEC usp_GetValue #ID, #Description
Select Top 1 #v_value = v_value From #tempresult
My advise is use the function approach.