RAISERROR Dosn't Work Inside CATCH With ROLLBACK TRANSACTION - sql

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.

Related

Transaction not working in SQL Server 2017

I have a transaction to check if an entry in my table has the same date and subHistoryID. Regardless if the data matches or not the transaction always rolls back. Any help on this matter would be great.
BEGIN TRANSACTION [Tran1]
INSERT INTO History(Name, subHistoryID, GarageID, StaffID, Date, Notes)
VALUES (#name, #subhistoryid, #garageid, #staffid, #date, #notes);
IF EXISTS (SELECT * FROM History
WHERE History.Date = #date AND History.subHistoryID = #subhistoryid)
BEGIN
ROLLBACK TRANSACTION [Tran1]
PRINT 'ERROR: Rolling back transaction.'
END
ELSE
BEGIN
PRINT 'PASS: Committing transaction.'
COMMIT TRANSACTION [Tran1]
END
GO
My data before attempting the transaction.
DECLARE #name varchar(20) = NULL;
DECLARE #subhistoryid int = 1;
DECLARE #garageid int = 1;
DECLARE #staffid int = 1;
DECLARE #date Date = '2018-10-21';
DECLARE #notes varchar(100) = 'test';
This data should roll back, which is does.
DECLARE #name varchar(20) = NULL;
DECLARE #subhistoryid int = 1;
DECLARE #garageid int = 1;
DECLARE #staffid int = 1;
DECLARE #date Date = '2016-1-1';
DECLARE #notes varchar(100) = 'test';
This data should commit, but it rolls back

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.

Stored Procedure does not insert data

I am going nuts with a SQL Server stored procedure, it is supposed to register an user into the database (If the user does not already exists). But, after successfully executing the procedure, no data is inserted into the Users table.
If I run the insert statement directly, it works.
Below is the full procedure code, before you ask me, the database is empty.
--USERS
CREATE PROCEDURE [dbo].[RegisterUser]
#NAME VARCHAR(255),
#PHONENUMBER VARCHAR(255),
#STATUS INT OUT,
#REMAININGDAYS INT OUT
AS
BEGIN
SET NOCOUNT ON;
UPDATE Users WITH (serializable)
SET Name = #NAME
WHERE PhoneNumber LIKE #PHONENUMBER
SET #REMAININGDAYS = 0
IF ##rowcount = 0
BEGIN
INSERT INTO Users (Name, PhoneNumber, RegisterDate)
VALUES (#NAME, #PHONENUMBER, GETDATE())
SET #STATUS = 0
SET #REMAININGDAYS = 40
END
ELSE
BEGIN
DECLARE #USERID BIGINT
DECLARE #EXP DATETIME
SELECT TOP 1
#USERID = USERID
FROM USERS
WHERE PhoneNumber LIKE #PHONENUMBER
SELECT TOP 1
#EXP = DATEADD(day, DAYS, REGISTERDATE)
FROM SUBSCRIPTIONS
WHERE USERID = #USERID
ORDER BY [REGISTERDATE]
IF #EXP IS NULL
BEGIN
SELECT TOP 1
#EXP = DATEADD(day, 40, REGISTERDATE)
FROM USERS
WHERE USERID = #USERID
IF GETDATE() < #EXP
BEGIN
SET #STATUS = 0
SET #REMAININGDAYS = DATEDIFF(day, GETDATE(), #EXP)
END
ELSE
BEGIN
SET #STATUS = -1
END
END
ELSE
BEGIN
IF GETDATE() < #EXP
SET #STATUS = 1
ELSE
SET #STATUS = -1
END
END
END
I call it passing all parameters.
Thank you!
Statements that make a simple assignment always set the ##ROWCOUNT value to 1. ##ROWCOUNT (Transact-SQL)
So
DECLARE #i int
SET #i = 0
PRINT ##ROWCOUNT
prints 1.
DECLARE #RC INT
UPDATE Users WITH (serializable) SET Name = #NAME
WHERE PhoneNumber LIKE #PHONENUMBER
SET #RC = ##ROWCOUNT
SET #REMAININGDAYS = 0
IF ##RC = 0
BEGIN
INSERT INTO Users <etc...>
Or move SET #REMAININGDAYS = 0 above the update statement so nothing between the update and the test of ##ROWCOUNT.

i want to decrease the quantity field and decrease its number

CREATE PROCEDURE dbo.IssueBook
(
#bookid nvarchar(50),
#ano nvarchar(50),
#mid int,
#librarian varchar(10),
#quantity int
)
AS
declare #cnt int
declare #msg varchar(100)
if not exists( select * from books where bookid = #bookid and quantity = #quantity)
begin
raiserror('Book is not available',16,1);
return;
end;
select #cnt = count(bookid) from issues where mid = #mid;
if ( #cnt >= 2 )
begin
raiserror('Maximum Limit Has Been Reached For Member!',16,1);
return;
end;
begin tran
begin try
update books set quantity =#quantity-1 where bookid= #bookid;
insert into issues values (#bookid, #mid, getdate(), #librarian, #ano);
commit tran
end try
begin catch
rollback tran
/* select #msg = error_message() */
raiserror( 'Unknown Error', 16,1);
end catch
i want to change value of quantity field in sql table how can i do that please help me i tried many things but they are not working i will be very thankful to you...
I think the problem is in this part: set quantity =#quantity-1. If I understand you correctly, it should either be
set quantity = quantity-1 -- Decreease the book quantity by 1
or
set quantity = quantity - #quantity -- Decreease the book quantity by #quantity

Yet another primary key exception

Last year I ask this question: What could be causing the primary key exception?
But I still have another error in this stored procedure: randomly I get
INSERT EXCEPTION WITH FOREIGN KEY "FK_Sessions" WITH TABLE
"Sessions", column "id".
CREATE PROCEDURE [dbo].[MyProcedure]
#sessionId varchar(512),
#variable varchar(350),
#value image
AS
BEGIN
BEGIN TRAN
DECLARE #result int = 0;
DECLARE #locked bit;
IF (SELECT COUNT(*) FROM Sessions WITH(ROWLOCK,HOLDLOCK) WHERE id = #sessionId) = 0
BEGIN
SET #result = -1;
END
ELSE BEGIN
DELETE Variables WITH(ROWLOCK,HOLDLOCK) WHERE sessionId = #sessionId AND variable = #variable
IF #value IS NOT NULL
BEGIN
INSERT Variables VALUES(#sessionId, #variable, #value, 0)
END
END
COMMIT TRAN
RETURN #result
END
Any ideas? Thanks again