Click here to Skip to main content
15,885,213 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
Hi folks
Hi was creating a simple stored procedure, as i tried to execute that procedure with the data already exist in table(just to check) I am getting following message

C#
(1 row(s) affected)


    (1 row(s) affected)

Msg 50000, Level 16, State 1, Procedure insert_loginDetails, Line 30
User Already exists
Msg 266, Level 16, State 2, Procedure insert_loginDetails, Line 2
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.
The 'insert_loginDetails' procedure attempted to return a status of NULL, which is not allowed. A status of 0 will be returned instead.


Query for the table that i created:
SQL
CREATE TABLE [dbo].[user_Login] (
    [user_id]           INT          IDENTITY (1000, 1) NOT NULL,
    [user_email]        VARCHAR (50) NOT NULL,
    [user_password]     VARCHAR (25) NOT NULL,
    [user_type]         VARCHAR (15) NOT NULL,
    [user_status]       VARCHAR (20) NOT NULL,
    [registration_date] DATETIME     NOT NULL,
    [last_login]        DATETIME     NOT NULL,
    [validation_code]   VARCHAR (50) NOT NULL,
    [validation_status] VARCHAR (20) NOT NULL,
    PRIMARY KEY CLUSTERED ([user_id] ASC),
    CONSTRAINT [chk_usertype] CHECK ([user_type]='superadmin' OR [user_type]='admin' OR [user_type]='user'),
    CONSTRAINT [chk_userstatus] CHECK ([user_status]='disabled' OR [user_status]='inactive' OR [user_status]='active' OR [user_status]='non validated'),
    CONSTRAINT [chk_validationstatus] CHECK ([validation_status]='email not sent' OR [validation_status]='non validated' OR [validation_status]='email sent' OR [validation_status]='validated')
);


Stored Procedure that i created. I am attaching the query for the table and the stored procedure
SQL
CREATE PROCEDURE [dbo].[insert_loginDetails]
	@user_email varchar(50) , @user_password varchar(25), @user_type varchar(15), @validation_code varchar(40), @user_id int OUTPUT
	
	AS
	SET XACT_ABORT on;
	BEGIN Transaction T1
	DECLARE @user_status varchar(20) = 'non validated'
	DECLARE @registration_date datetime = GETDATE()
	DECLARE @last_login datetime = GETDATE()
	DECLARE @validation_status varchar(20) = 'non validated'

	IF NOT Exists (select 1 from user_Login where user_email = @user_email)
	BEGIN
	insert into user_Login values(@user_email, @user_password, @user_type, @user_status, @registration_date, @last_login, @validation_code, @validation_status)
	PRINT('user Details are inserted successfully')
   
   if @@ERROR <> 0
   BEGIN
   if @@TRANCOUNT> 0
   BEGIN
   ROLLBACK
   RAISERROR('User Login information insertion has failed',16,1)
   END
  END
    
	

   END
   ELSE
   BEGIN
   RAISERROR('User Already exists',16,1)
   END

if @@ERROR= 0
COMMIT TRANSACTION T1
SELECT @user_id=@@IDENTITY from user_Login
 RETURN @user_id


I am not able to figure out whats wrong with my stored procedure
Posted
Updated 23-Jul-13 9:16am
v2
Comments
Maciej Los 23-Jul-13 15:31pm    
Please read the message carefully and check the number of END in IF () BEGIN ... END ... ELSE BEGIN ... END code block.
ZurdoDev 23-Jul-13 22:05pm    
RAISERROR will not exit so you'll want to use a Return statement, if that is what you are trying to do.
mgoad99 23-Jul-13 18:22pm    
Try removing the if @@ERROR = 0 before the COMMIT line.

If you get to that point without having already saying ROLLBACK, then COMMIT. No need to check first.

I think that is why you are getting the error: Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements

Error1: User Defined Error so no need to worry about it..
Error2: Try ROLLBACK TRANSACTION T1 instead of ROLLBACK
Error3: After an INSERT, SELECT INTO, or bulk copy statement is completed, @@IDENTITY contains the last identity value that is generated by the statement.If the statement did not affect any tables with identity columns, @@IDENTITY returns NULL. so try using ISNULL()..

MSDN Suggests using THROW instead of RAISEERROR While Using XACT_ABORT
http://msdn.microsoft.com/en-us/library/ms188792.aspx[^]

Try using this Code..
SQL
CREATE PROCEDURE [dbo].[insert_loginDetails]
       @user_email varchar(50) , 
       @user_password varchar(25), 
       @user_type varchar(15),  
       @validation_code varchar(40), 
       @user_id int OUTPUT
AS
Begin
    SET XACT_ABORT ON;
    BEGIN Transaction T1
    DECLARE @user_status varchar(20) = 'non validated'
    DECLARE @registration_date datetime = GETDATE()
    DECLARE @last_login datetime = GETDATE()
    DECLARE @validation_status varchar(20) = 'non validated'
 
    IF NOT Exists (select 1 from user_Login where user_email = @user_email)
    BEGIN
       insert into user_Login values(@user_email, @user_password, @user_type, @user_status, @registration_date, @last_login, @validation_code, @validation_status)
       PRINT('user Details are inserted successfully') 
    END
    ELSE
       Throw 50000,'User Already exists',1
 
     if @@ERROR= 0
	COMMIT TRANSACTION T1;
     Else if @@TRANCOUNT <>0
     BEGIN
	ROLLBACK TRANSACTION T1;
	Throw 50000,'User Login information insertion has failed',1
     END

     SELECT @user_id=@@IDENTITY from user_Login -- Try isnull() Here
     RETURN 
End


Hope this helps...
 
Share this answer
 
v8
SQL
CREATE PROCEDURE [dbo].[insert_loginDetails]
	@user_email varchar(50) , @user_password varchar(25), @user_type varchar(15), @validation_code varchar(40), @user_id int OUTPUT
	
	AS
	SET XACT_ABORT on;
	BEGIN Transaction T1
	DECLARE @user_status varchar(20) = 'non validated'
	DECLARE @registration_date datetime = GETDATE()
	DECLARE @last_login datetime = GETDATE()
	DECLARE @validation_status varchar(20) = 'non validated'

	IF NOT Exists (select 1 from user_Login where user_email = @user_email)
	BEGIN
	insert into user_Login values(@user_email, @user_password, @user_type, @user_status, @registration_date, @last_login, @validation_code, @validation_status)
	PRINT('user Details are inserted successfully')
   
   if @@ERROR <> 0
   BEGIN
   if @@TRANCOUNT> 0
   BEGIN
   ROLLBACK TRANSACTION T1
   RAISERROR('User Login information insertion has failed',16,1)
   END
  END
    
	

   END
   ELSE
   BEGIN
   ROLLBACK TRANSACTION T1
   RAISERROR('User Already exists',16,1)
   RETURN
   END

if @@ERROR= 0
COMMIT TRANSACTION T1
SELECT @user_id=@@IDENTITY from user_Login
 RETURN ISNULL(@user_id,NULL)



I brought some changes as you people suggested, and this works pretty fine.

Please check it, if this is a good way?

Mr. Raja Shekhar, your solution has really proved helpfull
 
Share this answer
 
Comments
Raja Sekhar S 25-Jul-13 1:54am    
Why are you using isnull(@user_id,NULL)..? The Purpose of isnull is to return some value if the variable is null... so if u use this isnull(var,Null) u are asking sql server to return null if var is null..u will again encounter the error "The 'insert_loginDetails' procedure attempted to return a status of NULL, which is not allowed. A status of 0 will be returned instead".

You Should use isnull while assigning value to @user_id like
select @user_id=isnull(@@Identity,0/*non null value like 0*/) from user login

While Writing if statements or begin end statements u have to give some space between code blocks so anyone can understand what part of code belongs to which if statement. Code Readability...

mark my amswer as solution if it helped...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900