Returns of an Update Stored Procedure - sql

I have this stored procedure on my SQL SERVER 2008:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SAVE1]
#IDKEY float,
#CPF nvarchar(20)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
UPDATE people SET NINUMBER = #CPF WHERE IDKEY = (SELECT IDKEY from contact where IDKEY= #IDKEY)
SELECT 1 as retorno
END TRY
BEGIN CATCH
SELECT 0 as retorno
END CATCH
END
But if I execute with a invalid IDKEY, the return is "1", but I thought would enter in the "CATCH" and return "0". What I'm doing wrong?

It won't throw an exception in this case. Your subquery simply would return no records, and therefore your update statement would execute against zero records. It would not fail though.

Your query is not failing instead it is returning no rows and hence it is returning 1. Try like this:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SAVE1]
#IDKEY float,
#CPF nvarchar(20)
AS
BEGIN
SET NOCOUNT ON;
UPDATE people SET NINUMBER = #CPF WHERE IDKEY = (SELECT IDKEY from contact where IDKEY= #IDKEY)
END
IF (##ROWCOUNT > 0)
BEGIN
SELECT 1 as retorno
END
ELSE
BEGIN
SELECT 0 as retorno
END

Related

decryption following hash for same Id is not working

I have two seperate stored procedures which one is for adding a new employee to DB and the other is for getting an employee from the DB.
I'm using SHA2_256 and it looks like it works good when inserting the data, but when using the same technique for getting the employee, something is not working.
This is the SP for adding the employee.
USE [db11]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[io_sp_admin_add_emp]
#Id BIGINT, #Lname VARCHAR(20), #Fname VARCHAR(15),#Gender TINYINT,#Bday DATETIME,#LoggedInUser VARCHAR(10)
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRY
DECLARE #HashId varbinary(50) = HashBytes('SHA2_256', cast(#Id as varbinary(50)))
INSERT INTO io_t_employees(
lname,
fname,
gender,
bday,
[user_name],
hash_id
)
VALUES(
LTRIM(RTRIM(#Lname)),
LTRIM(RTRIM(#Fname)),
#Gender,
#Bday,
#loggedInUser,
#HashId,
)
SELECT CAST(1 as BIT) as 'Status', 'Succeeded' as 'ReturnMessage'
END TRY
BEGIN CATCH
END
And Then, I would like to get the User's UniqueId according to the HashId stored earlier.
USE [db11]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[io_sp_admin_emp_helper]
-- Add the parameters for the stored procedure here
#id INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT UniqueId
FROM io_t_employees
WHERE hash_id = HashBytes('SHA2_256', cast(#id as varbinary(50)))
END
Unfortunately ,the result of the second procedure's query has no data.
I have a feeling I'm doing something wrong in the first procedure (add employee).

how to catch multiple transaction error and set it to output parameter

I am new to T-SQL programming. I have write the following sub program to implement two transactions. I need to use three output parameter to record the error. I need to initially set #P_Return_Status = 'S'.
If On error, in the CATCH block, I need to ROLLBACK the transaction; Set #P_Return_Status = ‘E’;Set #P_Error_Code = Error_Number();Set #P_Error_Messages = Error_Message()
How could I output the error for multiple (here is two) transactions and being caught by the main program. Forgive me if my code are totally wrong since I am very new to T-SQL.
IF OBJECT_ID('dbo.sub_Initialize') IS NULL -- check if SP Exist
EXE('CREATE PROCEDURE dbo.sub_Initialize AS SET NOCOUNT ON;')
GO
ALTER PROCEDURE dbo.sub_Initialize
(
#P_CurrentPeriod VARCHAR(12)
#P_Return_Status VARCHAR(1) OUT,
#P_Error_Code INT OUT,
#P_Error_Messages VARCHAR(2000) OUT
)
AS
BEGIN
SET #P_Return_Status VARCHAR(1) = 'S'
SET #P_Error_Code INT = NULL
SET #P_Error_Messages VARCHAR(2000) = NULL
BEGIN TRANSACTION
BEGIN TRY
IF EXISTS (SELECT 1 FROM Rollup_Elemental_Costs WHERE Rpt_Period = #P_CurrentPeriod)
DELETE FROM Rollup_Elemental_Costs
WHERE Rpt_Period = #P_CurrentPeriod
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
SET #P_Return_Status = ‘E’
SET #P_Error_Code = ERROR_CODE()
SET #P_Error_Messages = ERROR_MESSAGE()
END CATCH
BEGIN TRANSACTION
BEGIN TRY
IF EXISTS (SELECT 1 FROM Rollup_Batch_Detail_Trx WHERE Rpt_Period = #P_CurrentPeriod)
DELETE FROM Rollup_Batch_Detail_Trx
WHERE Rpt_Period = #P_CurrentPeriod
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
SET #P_Return_Status = 'E'
SET #P_Error_Code = ERROR_NUMBER()
SET #P_Error_Messages = ERROR_MESSAGE()
END CATCH
END
I would suggest you to create a table for storing error messages. Then insert each transaction error message into the table so that you can query the error table later to find out the error messages in transaction.
Create table error_Message
(
Transaction_identification Varchar(20) --To identify which trans generated error message
Return_Status VARCHAR(1),
Error_Code INT,
Error_Messages VARCHAR(2000)
)
You may have to add some more columns to identify transaction details
Note : If you don't want to store error messages in physical table then convert the same to temp table inside procedure. Then at the end of procedure you can return the temp table results
Then inside CATCH block you can insert into the error_Message table
BEGIN CATCH
ROLLBACK TRANSACTION;
Insert into error_Message(Transaction_identification,Return_Status,Error_Code,Error_Me
select 'Trans 1',‘E’,ERROR_CODE(),ERROR_MESSAGE()
END CATCH

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

T-SQL: How to return 0 rows in from stored procedure, and how to use XACT_ABORT and TRY/CATCH

I'm writing a stored procedure and I want to return 0 records when something fails. I can't seem to figure out how to just return 0 rows? I've used SELECT NULL but this returns 1 row with a NULL in row 1 col 1. I have also tried not specifying any SELECT statements in my error code path but when testing the value of ##ROWCOUNT after the call to the SP, it returned 1. I think this may be because the ##ROWCOUNT was never reset from the SELECT statement earlier in the SP (in the EXISTS()). Any advice would be appreciated.
Also, I've got XACT_ABORT set to ON, but I have also used a TRY/CATCH block to ensure I return the correct error "return value" from the stored procedure. Is this okay? If there is an error, will the XACT_ABORT override the TRY/CATCH or will my error code path still lead to the correct return values being returned?
-- Setup
SET NOCOUNT ON; -- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements.
SET XACT_ABORT ON; -- SET XACT_ABORT ON rollback transactions on errors
DECLARE #return int; SET #return = 1; -- Default to general error
-- Start transaction
BEGIN TRANSACTION
BEGIN TRY
IF NOT EXISTS(SELECT NULL FROM [MyTable] WHERE [Check] = 1)
BEGIN
-- Insert new record
INSERT INTO [MyTable] (Check, Date) VALUES (1, GETDATE());
SELECT SCOPE_IDENTITY() AS [MyValue]; -- Return 1 row
SET #return = 0; -- Success
END
ELSE
BEGIN
-- Fail
SELECT NULL AS [MyValue]; -- Want to return 0 rows not 1 row with NULL
SET #return = 2; -- Fail error
END
END TRY
BEGIN CATCH
-- Error
ROLLBACK TRANSACTION;
SELECT NULL AS [MyValue]; -- Want to return 0 rows not 1 row with NULL
SET #return = 1; -- General error
END CATCH
-- End transaction and return
COMMIT TRANSACTION
RETURN #return;
To return 0 rows, you can do:
SELECT TOP 0 NULL AS MyValue
Personally, I'd use an OUTPUT parameter for this sproc to return the ID back out instead of returning a resultset - that's just my preference though. Then just set that output parameter to e.g. -1 as default to indicate nothing done.
this is how I'd do it:
CREATE PROCEDURE YourProcedure
AS
( #NewMyValue int OUTPUT --<<<<<use output parameter and not a result set
)
BEGIN TRY
--<<<<put everything in the BEGIN TRY!!!
-- Setup
SET NOCOUNT ON; -- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements.
SET XACT_ABORT ON; -- SET XACT_ABORT ON rollback transactions on errors
DECLARE #return int
--<<init multiple variables in a select, it is faster than multiple SETs
--set defaults
SELECT #return = 1 -- Default to general error
,#NewMyValue=NULL
-- Start transaction
BEGIN TRANSACTION --<<<put the transaction in the BEGIN TRY
--<<<lock rows for this transaction using UPDLOCK & HOLDLOCK hints
IF NOT EXISTS(SELECT NULL FROM [MyTable] WITH (UPDLOCK, HOLDLOCK) WHERE [Check] = 1)
BEGIN
-- Insert new record
INSERT INTO [MyTable] (Check, Date) VALUES (1, GETDATE());
SELECT #NewMyValue=SCOPE_IDENTITY() --<<<set output parameter, no result set
,#return = 0; -- Success
END
ELSE
BEGIN
-- Fail
--<<no need for a result set!!! output parameter was set to a default of NULL
SET #return = 2; -- Fail error
END
COMMIT TRANSACTION --<<<commit in the BEGIN TRY!!!
END TRY
BEGIN CATCH
-- Error
IF XACT_STATE()!=0 --<<<only rollback if there is a bad transaction
BEGIN
ROLLBACK TRANSACTION
END
--<<any insert(s) into log tables, etc
--<<no need for a result set!!! output parameter was set to a default of NULL
SET #return = 1; -- General error
END CATCH
-- End transaction and return
RETURN #return;
GO