how to handle procedure wrong input parameters error using exception block - sql-server

CREATE PROCEDURE sp_product_listing
(
#product varchar(30),
#month datetime,
#year datetime
)
AS
SELECT
'product_name' = products.name,
products.unit_price,
products.quantity_in_stock,
'supplier_name' = suppliers.name
FROM
suppliers
INNER JOIN
products ON suppliers.supplier_id = products.supplier_id
INNER JOIN
order_details ON products.product_id = order_details.product_id
INNER JOIN
orders ON order_details.order_id = orders.order_id
WHERE
products.name = #product
AND MONTH ('orders.order_date') = #month
AND YEAR ('orders.order_date') = #year;
GO
When some try to execute the procedure with wrong input, instead of getting this error message catch in exception block
Msg 8114, Level 16, State 5, Procedure sp_product_listing, Line 0
Error converting data type varchar to datetime.

From my comments : It is impossible to validate the input pram of an SP inside the same sp !
You need to undergo a validation of input prams.
So hear is an simple example to do this with error handling method.
GO
CREATE PROCEDURE ERROR_TEST
(
#month DATETIME,
#year DATETIME
)
AS
BEGIN
SELECT
MONTH (#month) [month],
YEAR (#year) [year]
END
GO
Now create a similar sp with same input prams.
GO
CREATE PROCEDURE ERROR_TEST_1
(
#month_1 VARCHAR(50),
#year_1 VARCHAR(50)
)
AS
BEGIN TRY
EXEC ERROR_TEST #month_1,#year_1
END TRY
BEGIN CATCH
IF ERROR_NUMBER() = 8114 --> update asper your error OR set > 0
BEGIN
PRINT 'INVALID MONTH OR YEAR'
END
END CATCH;
GO
Sample Execution :
EXEC ERROR_TEST_1 '1','2' ---> Error result
EXEC ERROR_TEST_1 '2015-11-15','2015-11-15'---> correct result

Related

insert data into sql table and get recent inserted iD and insert data in same table from different table

Here is the situation that I have to insert profile photos in the SQL table. But here are 2 scenarios the condition
if user is inserting photo and data from front end. Its working perfectly fine.
if user is skip the photo and just inserting his biography then in that case the default image should be inserted by default. I tried to do in front end Just adding dummy image in if else condition, but in DMZ server for some reason this is creating problem, on local server its working good.
Here is the Query...
ALTER PROCEDURE [dbo].[SavePhysicianBiodata]
-- Add the parameters for the stored procedure here
#ID int,
#Physician_Bio nvarchar(MAX),
#Physician_Mnemonic nvarchar(MAX),
#Physician_Image image,
#Physician_ImageType nvarchar(MAX),
#Physician_ImageFileName nvarchar(MAX)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
if( #ID is null OR #ID='')
begin
--if not image then deafult image will be applied
if((#Physician_ImageType is null or #Physician_ImageType='') and
(#Physician_ImageFileName is null or #Physician_ImageFileName='') )
begin
insert into Physician_Biodata(Physician_Bio, Physician_Mnemonic)
values(#Physician_Bio, #Physician_Mnemonic)
set #ID = SCOPE_IDENTITY()
update [dbo].[Physician_Biodata]
set Physician_Image=#Physician_Image,
Physician_ImageType=#Physician_ImageType,
Physician_ImageFileName=#Physician_ImageFileName
where ID=#ID
end
else
begin
-- Insert statements for procedure here when user adds photo as well
insert into Physician_Biodata(Physician_Bio, Physician_Mnemonic,
Physician_Image, Physician_ImageType, Physician_ImageFileName)
values(#Physician_Bio, #Physician_Mnemonic,
#Physician_Image,#Physician_ImageType,#Physician_ImageFileName)
end
end
else
begin
update [dbo].[Physician_Biodata]
set Physician_Bio=#Physician_Bio,
Physician_Mnemonic=#Physician_Mnemonic,
Physician_Image=#Physician_Image,
Physician_ImageType=#Physician_ImageType,
Physician_ImageFileName=#Physician_ImageFileName
where ID=#ID
end
END
In this query I also tried insert query which is given below
insert into Physician_Biodata(ID, Physician_Image, Physician_ImageType, Physician_ImageFileName)
select #ID, dd.Physician_Image,dd.Physician_ImageType,dd.Physician_ImageFileName from DefaultImage as dd
join Physician_Biodata
on Physician_Biodata.Physician_ImageFileName = dd.Physician_ImageFileName
where Physician_Biodata.ID = #ID
but getting error during execute procedure
Msg 544, Level 16, State 1, Procedure dbo.SavePhysicianBiodata, Line 35 [Batch Start Line 2]
Cannot insert explicit value for identity column in table 'Physician_Biodata' when IDENTITY_INSERT is set to OFF.
If somebody can help me it would be great.. Thanks in advance.
Yes I have already changed the first insert statement (removed ID) and
updated the 2nd query
set #ID = IDENT_CURRENT('Physician_Biodata')
update Physician_Biodata
set Physician_Biodata.Physician_Image= DefaultImage.Physician_Image, Physician_Biodata.Physician_ImageType= DefaultImage.Physician_ImageType, Physician_Biodata.Physician_ImageFileName=DefaultImage.Physician_ImageFileName from Physician_Biodata, DefaultImage where Physician_Biodata.ID=#ID
and it worked
It appears that Physician_Biodata's ID column is an IDENTITY, hence the exception you have.
Changing this...
INSERT INTO Physician_Biodata (
ID, Physician_Image, Physician_ImageType, Physician_ImageFileName
)
SELECT
#ID,
dd.Physician_Image,
dd.Physician_ImageType,
dd.Physician_ImageFileName
FROM DefaultImage AS dd
JOIN Physician_Biodata
ON Physician_Biodata.Physician_ImageFileName = dd.Physician_ImageFileName
WHERE
Physician_Biodata.ID = #ID;
To this...
INSERT INTO Physician_Biodata (
Physician_Image, Physician_ImageType, Physician_ImageFileName
)
SELECT
dd.Physician_Image,
dd.Physician_ImageType,
dd.Physician_ImageFileName
FROM DefaultImage AS dd
JOIN Physician_Biodata
ON Physician_Biodata.Physician_ImageFileName = dd.Physician_ImageFileName
WHERE
Physician_Biodata.ID = #ID;
Will make your "explicit value" exception go away as in your INSERT you are attempting to insert #ID into ID which is an identity column. You also use ID = #ID in your WHERE clause, which makes inserting #ID pointless as this would be a chicken-and-egg issue.
On another note, if #Physician_ImageType and #Physician_ImageFileName are both NULL going in, they'll still be NULL on your UPDATE given your existing SP's logic.
I've taken a little liberty to tidy/simplify your T-SQL and added a note about what I've questioned.
ALTER PROCEDURE [dbo].[SavePhysicianBiodata] (
#ID int,
#Physician_Bio nvarchar(MAX),
#Physician_Mnemonic nvarchar(MAX),
#Physician_Image image,
#Physician_ImageType nvarchar(MAX),
#Physician_ImageFileName nvarchar(MAX)
)
AS
BEGIN
SET NOCOUNT ON;
IF ISNULL( #ID, '' ) = ''
BEGIN
--if not image then deafult image will be applied
IF ISNULL( #Physician_ImageType, '' ) = '' AND ISNULL( #Physician_ImageFileName, '' ) = ''
BEGIN
INSERT INTO Physician_Biodata ( Physician_Bio, Physician_Mnemonic )
VALUES ( #Physician_Bio, #Physician_Mnemonic ) ;
SET #ID = SCOPE_IDENTITY();
/*
Where are you setting the values for #Physician_Image, #Physician_ImageType, and #Physician_ImageFileName? These are still NULL?
*/
UPDATE [dbo].[Physician_Biodata]
SET
Physician_Image = #Physician_Image,
Physician_ImageType = #Physician_ImageType,
Physician_ImageFileName = #Physician_ImageFileName
WHERE
ID = #ID;
END
ELSE BEGIN
-- Insert statements for procedure here when user adds photo as well
INSERT INTO Physician_Biodata (
Physician_Bio, Physician_Mnemonic, Physician_Image, Physician_ImageType, Physician_ImageFileName
)
VALUES (
#Physician_Bio, #Physician_Mnemonic, #Physician_Image, #Physician_ImageType, #Physician_ImageFileName
);
END
END
ELSE BEGIN
UPDATE [dbo].[Physician_Biodata]
SET
Physician_Bio = #Physician_Bio,
Physician_Mnemonic = #Physician_Mnemonic,
Physician_Image = #Physician_Image,
Physician_ImageType = #Physician_ImageType,
Physician_ImageFileName = #Physician_ImageFileName
WHERE
ID = #ID;
END
END

Cannot see expected PRINT or RAISERROR output when a later error is raised

I'm getting an error message in a stored procedure, saying that I can't insert a NULL value into a table, when I should be getting errors earlier in the code if the value is null.
Here's the relevant part of the stored procedure:
CREATE PROCEDURE [dbo].[udp_AddUpdateStaffVariable]
-- Add the parameters for the stored procedure here
#StaffID int=null,
#VariableTypeID int,
#VariableIntValue int=null,
#VariableVarcharValue varchar(max)=null,
#VariableDatetimeValue datetime=null,
#VariableDecimalValue decimal=null
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
BEGIN TRY
DECLARE #PrintOutput varchar(150)
SET #PrintOutput = '#StaffID = ' + CASE WHEN #StaffID = NULL THEN 'Null' ELSE CONVERT(varchar(20), #StaffID) END
RAISERROR (#PrintOutput, 10, 1) WITH NOWAIT
IF (#StaffID = NULL) -- If the staffid of the current user was not supplied, find it in the Staff table
BEGIN
DECLARE #CurrentUser nvarchar(255) = SUSER_SNAME();
SELECT #StaffID = [StaffID] FROM [dbo].[Staff] WHERE [UserName] = #CurrentUser;
SET #PrintOutput = '#StaffID = ' + CASE WHEN #StaffID = NULL THEN 'Null' ELSE CONVERT(varchar(20), #StaffID) END
RAISERROR (#PrintOutput, 10, 1) WITH NOWAIT
IF #StaffID = NULL -- raise error if staffid wasn't found
BEGIN
RAISERROR (50001 --error number
, 16 -- severity
, 1 --state
, #CurrentUser -- parameter
)
END
END
-- Get the variable data type (used to determine where the variable is stored)
DECLARE #VarDataTypeDesc varchar(20)
DECLARE #StaffVarID int
SELECT #VarDataTypeDesc = dt.[StaffVariableDataType]
FROM [list].[DataTypes] dt INNER JOIN [list].[StaffVariableTypes] svt ON dt.DataTypeID = svt.DataTypeID
WHERE svt.VariableTypeID = #VariableTypeID
-- update or add the staff variable
IF EXISTS (SELECT 1 FROM [dbo].[StaffVariables] WHERE StaffID = #StaffID AND [VariableTypeID] = #VariableTypeID) -- update
BEGIN
IF #VarDataTypeDesc = 'int'
BEGIN -- only update here - other data types are updated further down
UPDATE [dbo].[StaffVariables] SET VariableIntValue = #VariableIntValue WHERE StaffID = #StaffID AND VariableTypeID = #VariableTypeID
END
ELSE -- StaffVariableID is only needed if the variable type is not int
BEGIN
SELECT #StaffVarID = StaffVariableID FROM [dbo].[StaffVariables] WHERE StaffID = #StaffID AND [VariableTypeID] = #VariableTypeID
END
END
ELSE -- insert
BEGIN
IF #VarDataTypeDesc = 'int'
BEGIN
INSERT INTO [dbo].[StaffVariables] (StaffID, VariableTypeID, VariableIntValue)
VALUES (#StaffID, #VariableTypeID, #VariableIntValue)
END
ELSE -- StaffVariableID is only needed if the variable type is not int
BEGIN
DECLARE #StaffVarIDTbl table(ID int)
INSERT INTO [dbo].[StaffVariables] (StaffID, VariableTypeID, VariableIntValue)
OUTPUT INSERTED.[StaffVariableID] INTO #StaffVarIDTbl
VALUES (#StaffID, #VariableTypeID, #VariableIntValue)
SELECT #StaffVarID = ID FROM #StaffVarIDTbl
END
END
-- Cutting out the section where I deal with other variable types besides int here - not relevant to this problem
END TRY
BEGIN CATCH
DECLARE #ErrorMessage NVARCHAR(4000);
DECLARE #ErrorSeverity INT;
DECLARE #ErrorState INT;
SELECT
#ErrorMessage = ERROR_MESSAGE(),
#ErrorSeverity = ERROR_SEVERITY(),
#ErrorState = ERROR_STATE();
-- Use RAISERROR inside the CATCH block to return error
-- information about the original error that caused
-- execution to jump to the CATCH block.
RAISERROR (#ErrorMessage, -- Message text.
#ErrorSeverity, -- Severity.
#ErrorState -- State.
);
END CATCH;
END
Here's the test procedure run code:
DECLARE #return_value int
EXEC #return_value = [dbo].[udp_AddUpdateStaffVariable]
#VariableTypeID = 1,
#VariableIntValue = 10
SELECT 'Return Value' = #return_value
GO
...and here's the response:
Msg 50000, Level 16, State 2, Procedure dbo.udp_AddUpdateStaffVariable, Line 130 [Batch Start Line 2]
Cannot insert the value NULL into column 'StaffID', table 'SnippingDbName.dbo.StaffVariables'; column does not allow nulls. INSERT fails.
(1 row affected)
Completion time: 2020-06-01T21:17:08.2049072-05:00
So... here's the question. The error seems to indicate that it either never ran the whole, if #StaffID = NULL portion of the code, or it did, and didn't find the StaffID and set the #StaffID variable. But if that were the case, why can't I see the results of my earlier RAISERROR statements?
I initially tried PRINT and switched to RAISERROR when PRINT wasn't working.
SQL Server 2017 Developer Edition, SSMS 15.0.18183.0
It was a syntax error, that people commenting on the question figured out. IF (#StaffID = NULL) should have been, IF (#StaffID IS NULL) Fixing that in all places in the procedure fixed the problem, and altering my test Staff record so UserName doesn't match SUSER_SNAME() resulted in the expected error.

SQL Proc 'Conversion failed' from varchar to int. Why the conversion?

My question here would be... Why is it converting to int from varchar? I'm not sure what it is trying to do
CREATE PROCEDURE #myTestProcedure
(
#TransId VARCHAR(15)
)
AS
BEGIN
DECLARE #Result VARCHAR(15);
WITH TestCTE (TransId, AdjRefTransId) AS
(
SELECT TRANSID, ADJREFTRANSID
FROM dbo.MyTable
WHERE TRANSID = #TransId
UNION ALL
SELECT pet.TRANSID, pet.ADJREFTRANSID
FROM dbo.MyTable AS pet
JOIN TestCTE
ON TestCTE.ADJREFTRANSID = pet.TRANSID
)
SELECT #Result =
(
SELECT MAX(MyResult)
FROM dbo.MyOtherTable
WHERE TRANSID = TestCTE.TRANSID
)
FROM TestCTE
WHERE TestCTE.ADJREFTRANSID = ''
RETURN #Result
END
EXEC dbo.#myTestProcedure #TransId = 'MyTransId'
Error:
Msg 245, Level 16, State 1, Procedure #myTestProcedure 0004C61A, Line 32
Conversion failed when converting the varchar value 'MyResult' to data type int.
I can't see where it is trying to make this conversion. Line 32 is a blank line. No code there.
It is your RETURN. Stored procedures return an integer to indicate the status of the execution, not return values. You would either need to Select #Result OR have #Result be an output parameter.

How can I include a Temp Table in a SQL Function

I have a SQL Server 2014 server linked to an Oracle server. I want to use a temp table in a function to return a dataset from the Oracle database and then use the my function to return results using regular T-SQL. Since I am rather new to this I am close but am getting an error message
Msg 156, Level 15, State 1, Procedure GetBond, Line 37
Incorrect syntax near the keyword 'BEGIN'.
I have posted the function code here:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[GetBond]
(#WarControlID bigint)
RETURNS VARCHAR(MAX)
AS
BEGIN
--Create Temp Table
declare #TSQL varchar(max)
DECLARE #WarrantBail table
(
WR_INVL varchar(5),
WR_WARR_CTL VarChar(10),
WR_Bail VarChar(50),
WC_BAIL VarChar(50)
)
SELECT #TSQL = 'SELECT * FROM OPENQUERY(RMSPROD2,''SELECT TIBURON.WRMAST.WR_INVL, TIBURON.WRMAST.WR_WARR_CTL,TIBURON.WRMAST.WR_BAIL,TIBURON.WRWCHG.WC_BAIL
FROM TIBURON.WRMAST
LEFT JOIN TIBURON.WRWCHG ON WRWCHG.WC_WR_CHAIN = WRMAST.WRMAST_ROW
WHERE TIBURON.WRMAST.WR_WARR_CTL = ''''' + #WarControlID + ''''''')'
INSERT INTO #WarrantBail
EXEC (#TSQL)
END
BEGIN
-- Create a Variable
DECLARE #NoBailCount int
DECLARE #ChgCount int
DECLARE #WarTotalBond float
DECLARE #CHGTotalBond float
DECLARE #War_Final_Bail varchar(max)
Select COUNT(DISTINCT w.WR_Bail) AS NoBond_Count
From #WarrantBail w
Where w.WC_BAIL In ('No Bond', 'No Bail','None') Or w.WR_Bail In ('No Bond', 'No Bail','None')
--***********Get Charge Count
Select COUNT(w.WC_BAIL) As ChgCount FROM #WarrantBail w
--******************IF the above fails then we have a bond check the Warrant bond amount
Select SUM (DISTINCT cast(w.WR_Bail As int)) AS WAR_Bond_Total
From #WarrantBail w
Where w.WR_Bail Not In ('No Bond', 'No Bail','None')
--****************We may have additional charges get the total for those charges
Select SUM (cast(w.WC_BAIL As int)) AS CHG_BondTotal
From #WarrantBail w
Where w.WC_BAIL Not In ('No Bond', 'No Bail','None')
IF (#NoBailCount > 0)
Begin
SET #War_Final_Bail = 'NO BAIL'
End
ELSE IF #ChgCount > 0
Begin
SET #War_Final_Bail = #WarTotalBond + #CHGTotalBond
End
Else
Begin
SET #War_Final_Bail = #WarTotalBond
End
RETURN CONVERT(varchar(max), #War_Final_Bail)
END
In addition to the Error when I Execute the code I am also seeing a squiggly line under the Line "ALTER FUNCTION [dbo].[GetBond]
That error states:
Incorrect syntax: 'ALTER FUNCTION' must be the only statement in this batch.
Does this error mean I cannot create a temp table in the function?
Why do you have an END and BEGIN here? Think this is likely (one of) your problem(s).
Insert Into #WarrantBail
EXEC (#TSQL)
END
BEGIN
-- Create a Variable
DECLARE #NoBailCount int
Do you absolutely have to use dynamic SQL? Why not do something like this...
INSERT INTO #WarrantBail
SELECT *
FROM OPENQUERY(RMSPROD2, '
SELECT TIBURON.WRMAST.WR_INVL,
TIBURON.WRMAST.WR_WARR_CTL,
TIBURON.WRMAST.WR_BAIL,
TIBURON.WRWCHG.WC_BAIL
FROM TIBURON.WRMAST
LEFT JOIN TIBURON.WRWCHG ON WRWCHG.WC_WR_CHAIN = WRMAST.WRMAST_ROW
WHERE TIBURON.WRMAST.WR_WARR_CTL = ' + CAST(#WarControlID AS VARCHAR(30)) + ')')
Thanks for your comments I am a junior developer and am just getting my first taste of SQL programming after a discussion with one of the senior developers I was able to complete the task by using a Stored Procedure.
Thank you for your comments.

How can I debug an SQL Server data issue that I can't seem to reproduce in any test environment?

I have a stored procedure in production that does 2 things. It updates one table and then inserts a record into another. The first step (the update) seems to occur but we've found instances by examining the data where the second step did not occur. I have looked at the data and confirmed that it is not a data issue. I've confirmed that the queries return the appropriate data in order to ensure that the queries complete and in normal circumstances both should execute. I don't know if perhaps there is some sort of performance issue ... or blocking issue that is occurring on the second step that prevents that step from occurring.
The error handling for the stored procedure is as follows.
BEGIN TRY
BEGIN TRANSACTION;
-- perform update to data
-- insert record into second table.
IF ( ##ERROR = 0 AND ##TRANCOUNT > 0 )
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF ( ##TRANCOUNT > 0 )
BEGIN
ROLLBACK TRANSACTION;
END
DECLARE #WebSafeErrorId INT;
EXEC dbo.spErrorInsert #WebSafeErrorId OUTPUT, 'Proc';
-- Reraise the error back to the client.
IF ( #WebSafeErrorId != 0 )
BEGIN
DECLARE #Error VARCHAR(20);
SET #Error = CAST( #WebSafeErrorId AS VARCHAR(20) );
RAISERROR( #Error, 11, 1 );
END
ELSE
BEGIN
RAISERROR( 'An error has occurred but there is no error to log.', 11, 1 );
END
END CATCH;
Surely if an error occurred in this procedure that cause the insert to not occur it would be logged and then raised. The code for spErrorInsert is below ...
CREATE PROCEDURE [dbo].[spErrorInsert]
#ReturnErrorId INT OUTPUT
, #ErrorSourceType VARCHAR(4) = NULL
, #ParentErrorId INT = NULL
, #StackTrace VARCHAR(MAX) = NULL
AS
SET NOCOUNT ON;
--SET XACT_ABORT ON;
-- Will indicate an error was not logged.
SET #ReturnErrorID = 0;
DECLARE
#ErrorSource VARCHAR(200)
, #ErrorMessage VARCHAR(MAX)
, #ComposedErrorMessage VARCHAR(MAX)
, #ErrorLine INT
, #ErrorSeverity INT
, #ErrorState INT
, #ErrorNumber INT;
SET #ErrorSource = ERROR_PROCEDURE();
SET #ErrorMessage = ERROR_MESSAGE();
SET #ErrorLine = ERROR_LINE();
SET #ErrorSeverity = ERROR_SEVERITY();
SET #ErrorState = ERROR_STATE();
SET #ErrorNumber = ERROR_NUMBER();
SET #ComposedErrorMessage = 'Message: Error occurred in procedure ' + CAST( #ErrorSource AS VARCHAR(MAX) )
+ ' on line ' + CAST( #ErrorLine AS VARCHAR(MAX) )
+ '. Error: ' + #ErrorMessage;
BEGIN TRY
INSERT INTO Errors(
ParentId
, ErrorSourceType
, ErrorSource
, [Message]
, [LineNo]
, Severity
, Stacktrace
, ts)
VALUES (#ParentErrorId
, #ErrorSourceType --#ErrorSourceType --- NOTE: move this into a parameter ...
, #ErrorSource
, #ComposedErrorMessage
, #ErrorLine
, #ErrorState
, #Stacktrace
, GETDATE()
);
SET #ReturnErrorId = SCOPE_IDENTITY();
END TRY
BEGIN CATCH
RAISERROR( 'An error has occurred but there is no error to log.', 11, 1 );
END CATCH;
I don't know if maybe there is a way to get a snapshot of what's going on the database at a specific time when a certain procedure is called ... I'm not sure how to determine if something isn't happening when it should? Are there any tools that I can make use of or sql features that I don't know about???
If you want to monitor the database, SQL Profiler is a good place to start but it is going to be deprecated.
Extended events are much more capable and I would suggest reading about those if you are really interested in monitoring what's going on.
As a thought, if your procedure code is using the same data to update the row as it is to insert to the other table, consider using OUTPUT.
Update table set col1 = 'value'
OUTPUT inserted.col INTO othertable
Where col3 = stuff
OUTPUT and OUTPUT INTO
Or if this is for some sort of Audit or Log table, you can use DELETED.col1
That will be the original value prior to it being updated. Note that INSERTED will return the value that you are updating or inserting, it's just called INSERTED for both.
If you have a copy of Visual Studio, try it. It allows you to step through stored procedures.
The approach I would try is to firstly take a copy of this procedure and comment out the try/catch. I have found that tsql does not raise errors if the error generating code is within a try/catch block - I guess this is the sql equivalent of an exception being handled by the catch clause.
I use a table in my database to keep a permanent record of errors as they occur (a trick I learned doing embedded programming)
The errors table creation code is :
CREATE TABLE dbo.errors (
id smallint NOT NULL IDENTITY(1, 1) PRIMARY KEY,
errordesc nvarchar (max) NOT NULL,
dateandtime smalldatetime NOT NULL, -- Date and time of last occurance
errorcount int NOT NULL) ;
My stored procedure for adding a record into the error table is:
CREATE PROCEDURE jc_diagnostics.jpwsp0005_adderrordescription(
#Errordescription nvarchar( max ))
AS
BEGIN
DECLARE
#Id smallint = 0 ,
#Currentcount int = 0;
IF((#Errordescription IS NULL) OR ( #Errordescription = ''))
BEGIN
SET #Errordescription = 'Error description missing';
END;
SELECT #Id = ( SELECT TOP ( 1 ) id
FROM jc_diagnostics.errors
WHERE errordesc = #Errordescription );
IF(#Id IS NOT NULL)
BEGIN
SELECT #Currentcount = (SELECT errorcount
FROM jc_diagnostics.errors
WHERE id = #Id );
SET #Currentcount = #Currentcount + 1;
UPDATE jc_diagnostics.errors
SET errorcount = #Currentcount
WHERE id = #Id;
UPDATE jc_diagnostics.errors
SET dateandtime = CONVERT(smalldatetime , GETDATE())
WHERE id = #Id;
END;
ELSE
BEGIN
--new entry
INSERT INTO jc_diagnostics.errors( errordesc ,
dateandtime ,
errorcount )
VALUES( #Errordescription ,
CONVERT(smalldatetime , GETDATE()) ,
1 );
END;
IF(#Id IS NULL)
BEGIN
SET #Id = SCOPE_IDENTITY( );
END;
RETURN #Id;
END;
The calling code when an error occurs is:
Declare #Failuredesc nvarchar(max) = 'Description of error';
EXEC #Retval = jc_diagnostics.jpwsp0005_adderrordescription #Failuredesc;
The return value #Retval contains the id of the record in the error table so you can look it up
Finally I would create some code to continuously call your procedure until an error is declared. You can then inspect the error table and see if this throws light on your problem.
Hope this helps.
Jude
Logically thinking - because you declare transaction before these 2 steps, any error would result in rollback of both transactions. So most likely there is no error at all here. I would suggest inspect your queries again as it seems that the problem could be in them rather than anywhere else. Please post the entire code if you like more suggestions.
Regards
Roman

Resources