Dont want Select variable displaying values - sql

It might be simple but I been having trouble figuring out.
I have a piece of code(Similar to Below Code) where I am assigning bunch of values to bunch of variables via select, it does the job but when I am running it I am getting result set which is causing my SSMS to crash is there way to avoid this....
DECLARE #Name VARCHAR(100)
DECLARE #LastName VARCHAR(100)
DECLARE #Address VARCHAR(100)
SELECT TOP 1
#Name = Name
#LastName = LastName
#Address = Address
From Person.Address
Where Name = 'Name'
Order By ID
I am using the above code in a loop where I am processing around 3-400K rows and pass this variables to a stored procedure, each top 1 select statement throws a result set causing my SSMS to crash I dont really need the select top 1 values to be displayed, any idea how to get rid of this?....
Any help would be much appreciated.
---As requested below is the code, I have hashed few things but this is what it is and I am running it from Query Analayzer as this is only 1 time process so we dont need SP to be created.
DECLARE #retstat INT
DECLARE #Name VARCHAR(255)
DECLARE #Lang TINYINT
DECLARE #Address CHAR(10)
DECLARE #ID INT
DECLARE #BranchSeqNo INT
DECLARE #AddressCode VARCHAR(10)
DECLARE #Address1 VARCHAR(50)
DECLARE #City VARCHAR(30)
DECLARE #State VARCHAR(3)
DECLARE #PostalCode VARCHAR(15)
DECLARE #Country VARCHAR(30)
SET #ID = NULL
UPDATE RAWClaimTable Set Processed = 0 where Processed is null
UPDATE RAWClaimTable SET ErrorCode = NULL ,ErrorMessage = NULL ,Processed = 0
WHERE ErrorMessage IS NOT NULL AND CLAIMID is null
WHILE EXISTS ( SELECT *
FROM RAWClaimTable
WHERE Processed = 0 )
BEGIN
-----Initialize Default Variables
SET #Lang = 0
SET #Address = 'Import'
SET #SaveMode = 0
SET #ID = Null
SELECT TOP 1
#LossDate = LossDate ,
#ClaimDate = ClaimDate ,
#OpenDate = OpenDate ,
#Receivedate = ReceiVeDate ,
#Name = Name ,
#Address = Address ,
#Address1 = Address1 ,
#City = City ,
#State = State ,
#PostalCode = PostalCode ,
#Country = Country
FROM RAWClaimTable
WHERE Processed = 0
ORDER BY ClaimID
BEGIN TRY
EXEC #RetStat = Usp_ProcessRawData #Lang, #Address, #SaveMode, #ID OUT,
#BranchSeqNo, #OriginalBranchSeqNo, #IncidentID,
#AssignmentTypeCode, #PartnershipID, #AccountID,
END TRY
BEGIN CATCH
SELECT #RetStat = ##Error
if ##Trancount > 0 rollback tran
IF #RetStat != 0
BEGIN
update RAWClaimTable set Errormessage = ERROR_MESSAGE() where ClaiMKey = #Name
END
END CATCH
IF #ID IS NOT NULL
BEGIN
UPDATE RAWClaimTable
SET ClaimID = #ID ,
Processed = 1
WHERE ClaiMKey = #Name
END
ELSE
BEGIN
UPDATE RAWClaimTable
SET Processed = 1
WHERE ClaiMKey = #Name
END
END

Use a CURSOR to loop thru your rows!
SET #Lang = 0
SET #Address = 'Import'
SET #SaveMode = 0
SET #ID = Null
DECLARE my_cursor CURSOR FOR
SELECT LossDate, ClaimDate, OpenDate, ReceiVeDate, Name, Address,
Address1, City, State, PostalCode, Country
FROM RAWClaimTable
WHERE Processed = 0
OPEN my_cursor
FETCH NEXT FROM my_cursor
INTO #LossDate, #ClaimDate, #OpenDate, #Receivedate, #Name, #Address,
#Address1, #City, #State, #PostalCode, #Country
WHILE ##FETCH_STATUS = 0
BEGIN
BEGIN TRY
EXEC #RetStat = Usp_ProcessRawData #Lang, #Address, #SaveMode, #ID OUT,
#BranchSeqNo, #OriginalBranchSeqNo, #IncidentID,
#AssignmentTypeCode, #PartnershipID, #AccountID,
END TRY
BEGIN CATCH
SELECT #RetStat = ##Error
if ##Trancount > 0 rollback tran
IF #RetStat != 0
BEGIN
update RAWClaimTable set Errormessage = ERROR_MESSAGE()
where ClaiMKey = #Name
END
END CATCH
IF #ID IS NOT NULL
BEGIN
UPDATE RAWClaimTable
SET ClaimID = #ID ,
Processed = 1
WHERE ClaiMKey = #Name
END
ELSE
BEGIN
UPDATE RAWClaimTable
SET Processed = 1
WHERE ClaiMKey = #Name
END
FETCH NEXT FROM my_cursor
INTO #LossDate, #ClaimDate, #OpenDate, #Receivedate, #Name, #Address,
#Address1, #City, #State, #PostalCode, #Country
END

Related

How to return the output of stored procedure into a string variable in SQL Server

I want to execute a stored procedure in SQL Server and assign the output to a string.
CREATE PROCEDURE sp_Check_User_Password
#name NVARCHAR(30),
#email NVARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #pass NVARCHAR(50)
IF EXISTS(SELECT dbo.Mitarbeiter.Name, dbo.Mitarbeiter.Email
FROM dbo.Mitarbeiter
WHERE dbo.Mitarbeiter.Name = #name
AND dbo.Mitarbeiter.Email = #email
BEGIN
SET #pass = dbo.Mitarbeiter.Password
END
ELSE
BEGIN
SET #pass = null
END
RETURN #pass
END
I have changed what I wrote wrong
Have a look on below sample, just add your stuff and it will work
CREATE PROCEDURE return_string
(#param1 NVARCHAR(10),
#param2 NVARCHAR(10),
#output NVARCHAR(10) OUT)
AS
BEGIN
IF (1=1)
SET #output = 'here'
else
SET #output = null
END
to test
declare #out nvarchar(10)
exec return_string 'firdt param', 'second param', #out out
select #out
I hope this will help you achive what you need.
So your SP would look like:
CREATE PROCEDURE sp_Check_User_Password
(
#name nvarchar(30),
#email nvarchar(50),
#pass nvarchar(50) OUT
)
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS(SELECT 1
FROM dbo.Mitarbeiter
WHERE dbo.Mitarbeiter.Name = #name
and dbo.Mitarbeiter.Email = #email)
BEGIN
SET #pass = (SELECT dbo.Mitarbeiter.Name
FROM dbo.Mitarbeiter
WHERE dbo.Mitarbeiter.Name = #name
and dbo.Mitarbeiter.Email = #email)
END
ELSE
BEGIN
SET #pass = null
END
END
I'll take a stab at it. Is this what you're trying to do?
CREATE PROCEDURE sp_Check_User_Password
#name nvarchar(30),
#email nvarchar(50)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #pass nvarchar(50) = null
IF EXISTS(SELECT dbo.Mitarbeiter.Email FROM dbo.Mitarbeiter
WHERE dbo.Mitarbeiter.Name = #name and dbo.Mitarbeiter.Email = #email)
BEGIN
SELECT #pass = dbo.Mitarbeiter.Email FROM dbo.Mitarbeiter
WHERE dbo.Mitarbeiter.Name = #name and dbo.Mitarbeiter.Email = #email
END
PRINT #pass
END

Stored procedure for Login Application

I have a table with the user details like
id
fname
lname
role
branch
email
password
I have a stored procedure for the login validation which takes the values of email and password, validates and send out the success message.
The validation is working now. I need to fetch the values of fname, lname, role and branch too.
Here is the code:
USE [Project]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[usp_loginuser]
(#Email varchar(100),
#password varchar(100)
)
AS
BEGIN
DECLARE #msg nvarchar(2048)
SET NOCOUNT ON
--select * from dbo.userdetails where email=#userEmail and pwd=#password
BEGIN TRY
Declare #flag bit
SET #flag = 0
IF EXISTS(Select * from userdetails
where ltrim(rtrim(email)) = ltrim(rtrim(#Email)) AND ltrim(rtrim(pwd)) = ltrim(rtrim(#password))
AND isactive = 1)
BEGIN
SET #flag =1;
END
ELSE
BEGIN
SET #flag =0;
END
SELECT #flag [IsSuccess]
END TRY
BEGIN CATCH
SET #msg = error_message()
RAISERROR (#msg, 16, 1)
END CATCH
SET NOCOUNT OFF
END
Here is the code
ALTER Procedure [dbo].[usp_loginuser]
(#Email varchar(100),
#password varchar(100),
#fname varchar(100) output,
#lname varchar(100) output
)
AS
BEGIN
DECLARE #msg nvarchar(2048)
SET NOCOUNT ON
BEGIN TRY
Declare #flag bit
SET #flag = 0
IF EXISTS(Select #fname = fname, #lname = lname from userdetails
where ltrim(rtrim(email)) = ltrim(rtrim(#Email)) AND ltrim(rtrim(pwd)) = ltrim(rtrim(#password))
AND isactive = 1)
BEGIN
SET #flag =1;
END
ELSE
BEGIN
SET #flag =0;
END
SELECT #flag [IsSuccess], #fname, #lname
END TRY
BEGIN CATCH
SET #msg = error_message()
RAISERROR (#msg, 16, 1)
END CATCH
SET NOCOUNT OFF
END
BEGIN TRY
Declare #flag bit
SET #flag = 0
IF EXISTS(Select * from userdetails
where ltrim(rtrim(email)) = ltrim(rtrim(#Email)) AND ltrim(rtrim(pwd)) = ltrim(rtrim(#password))
AND isactive = 1)
BEGIN
SET #flag =1;
END
ELSE
BEGIN
SET #flag =0;
END
SELECT fname, lname, role, branch from userdetails
where ltrim(rtrim(email)) = ltrim(rtrim(#Email)) AND ltrim(rtrim(pwd)) = ltrim(rtrim(#password))
END TRY
If you get an empty data set, its a failure else success

SQL Server stored procedure returning Null instead of an INtT

I have this stored procedure:
#upc AS VARCHAR(13) = NULL,
#cert_code AS VARCHAR(15) = NULL,
#vendor AS INT = NULL,
#count AS INT = 0 OUTPUT,
#store AS VARCHAR(3) = NULL,
#corporate AS VARCHAR = Null,
#zone AS VARCHAR = Null,
#region AS VARCHAR = Null,
#class AS VARCHAR = Null
AS
BEGIN -- Added for new functionality
SET NOCOUNT ON;
If #store IS NOT NULL
BEGIN
-- Get the storeID from Stores
DECLARE #storeID AS INT
SELECT #storeID = StoreID
FROM Enterprise..Stores
WHERE Store = #store
END
IF #storeID IS NOT NULL
BEGIN
IF #cert_code IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsStore
WHERE (StoreID = #storeID) AND (upc = #upc)
END
ELSE
BEGIN
IF #vendor IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsStore
WHERE (StoreID = #storeID) AND (cert_code = #cert_code)
END
ELSE
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsStore
WHERE (StoreID = #storeID)
AND (cert_code = #cert_code) AND (vendor = #vendor)
END
END
END
END
If #zone IS NOT NULL
BEGIN
IF #cert_code IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsZone
WHERE (upc = #upc)
END
ELSE
BEGIN
IF #vendor IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsZone
WHERE (cert_code = #cert_code)
END
ELSE
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsZone
WHERE (cert_code = #cert_code) AND (vendor = #vendor)
END
END
END
IF #region IS NOT NULL
BEGIN
IF #cert_code IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsRegion
WHERE (upc = #upc)
END
ELSE
BEGIN
IF #vendor IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsRegion
WHERE (cert_code = #cert_code)
END
ELSE
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsRegion
WHERE (cert_code = #cert_code) AND (vendor = #vendor)
END
END
END
IF #class IS NOT NULL
BEGIN
IF #cert_code IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsClass
WHERE (upc = #upc)
END
ELSE
BEGIN
IF #vendor IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsClass
WHERE (cert_code = #cert_code)
END
ELSE
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsClass
WHERE (cert_code = #cert_code) AND (vendor = #vendor)
END
END
END
IF #corporate IS NOT NULL
BEGIN
IF #cert_code IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsMaster
WHERE (upc = #upc)
END
ELSE
BEGIN
IF #vendor IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsMaster
WHERE (cert_code = #cert_code)
END
ELSE
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsMaster
WHERE (cert_code = #cert_code) AND (vendor = #vendor)
END
END
END
GO
When I have #store IS NOT NULL it counts and returns an INT as expected, however when one of #corporate, #zone, #region, #class is set as NOT NULL, I am getting an output of null instead of an INT like expected.
What is the problem here?
I don't know if its a typo error or something else but please check you begin and ends for the IF and ELSE
From what I see the procedure ends within this set of codes as the END matches the BEGIN of the main stored procedure.
#upc AS VARCHAR(13) = NULL,
#cert_code AS VARCHAR(15) = NULL,
#vendor AS INT = NULL,
#count AS INT = 0 OUTPUT,
#store AS VARCHAR(3) = NULL,
#corporate AS VARCHAR = Null,
#zone AS VARCHAR = Null,
#region AS VARCHAR = Null,
#class AS VARCHAR = Null
AS
BEGIN -- Added for new functionality
SET NOCOUNT ON;
If #store IS NOT NULL
BEGIN
-- Get the storeID from Stores
DECLARE #storeID AS INT
SELECT #storeID = StoreID
FROM Enterprise..Stores
WHERE Store = #store
END
IF #storeID IS NOT NULL
BEGIN
IF #cert_code IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsStore
WHERE (StoreID = #storeID) AND (upc = #upc)
END
ELSE
BEGIN
IF #vendor IS NULL
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsStore
WHERE (StoreID = #storeID) AND (cert_code = #cert_code)
END
ELSE
BEGIN
SELECT #count = COUNT(*)
FROM Enterprise..ProductsStore
WHERE (StoreID = #storeID)
AND (cert_code = #cert_code) AND (vendor = #vendor)
END
END
END
END -- This End is wrong should not be here
If this is just a typo please post the codes properly.
Also as others have pointed out initialize the #count parameter as zero.
It seems the remaining part of the procedure is never executed and as #count is not initialized it returns Null
Why you put varchar?
Use bellow code.
#corporate AS VARCHAR(max) = NULL,
#zone AS VARCHAR(max) = NULL,
#region AS VARCHAR(max) = NULL,
#class AS VARCHAR(max) = NULL
None of your queries should be able to assign a null to your #count variable since they all use the count() aggregate. That means none of the queries is ever run.
I do think the end just prior to the if #zone is wrong. But I'm pretty sure that the end at the end of the procedure definition must be the end of the batch. Maybe I'm wrong and your proc is actually ending earlier than you expected?
You can certainly compress a lot of that branching into your queries. Here's my attempt at it. I pared down most of the indentation and begin/end pairs.
declare #storeID as int;
if #store is not null
begin
-- Get the storeID from Stores
SELECT #storeID = StoreID
FROM Enterprise..Stores
WHERE Store = #store;
if #storeID is not null
SELECT #count = COUNT(*)
FROM Enterprise..ProductsStore
WHERE StoreID = #storeID and
(
#cert_code is null and upc_code = #upc_code
or cert_code = #cert_code and (vendor = #vendor or #vendor is null)
);
end
if #zone is not null
SELECT #count = COUNT(*)
FROM Enterprise..ProductsZone
WHERE #cert_code is null and upc_code = #upc_code
or cert_code = #cert_code and (vendor = #vendor or #vendor is null);
if #region is not null
SELECT #count = COUNT(*)
FROM Enterprise..ProductsRegion
WHERE #cert_code is null and upc_code = #upc_code
or cert_code = #cert_code and (vendor = #vendor or #vendor is null);
if #class is not null
SELECT #count = COUNT(*)
FROM Enterprise..ProductsClass
WHERE #cert_code is null and upc_code = #upc_code
or cert_code = #cert_code and (vendor = #vendor or #vendor is null);

Getting Request Timeout sometimes from only one SP?

I have a lot of stored procedures. But I am only getting Request Timeout sometimes only for this SP ?
ALTER PROCEDURE [dbo].[Insertorupdatedevicecatalog]
(#OS NVARCHAR(50)
,#UniqueID VARCHAR(500)
,#Longitude FLOAT
,#Latitude FLOAT
,#Culture VARCHAR(10)
,#Other NVARCHAR(200)
,#IPAddress VARCHAR(50)
,#NativeDeviceID VARCHAR(50))
AS
BEGIN
SET NOCOUNT ON;
DECLARE #TranCount INT;
SET #TranCount = ##TRANCOUNT;
DECLARE #OldUniqueID VARCHAR(500) = ''-1'';
SELECT #OldUniqueID = [UniqueID] FROM DeviceCatalog WHERE (#NativeDeviceID != '''' AND [NativeDeviceID] = #NativeDeviceID);
BEGIN TRY
IF #TranCount = 0
BEGIN TRANSACTION
ELSE
SAVE TRANSACTION Insertorupdatedevicecatalog;
DECLARE #Geo GEOGRAPHY = geography::STGeomFromText(''POINT('' + CONVERT(VARCHAR(100), #Longitude) + '' '' + CONVERT(VARCHAR(100), #Latitude) + '')'', 4326);
IF EXISTS(SELECT 1 FROM DeviceCatalog WHERE [UniqueID] = #UniqueID)
BEGIN
DECLARE #OldGeo GEOGRAPHY
,#OldCity NVARCHAR(100)
,#OldCountry NVARCHAR(100)
,#OldAddress NVARCHAR(100);
SELECT #OldGeo = [LastUpdatedLocationFromJob]
,#OldCity = [City]
,#OldCountry = [Country]
,#OldAddress = [Address]
FROM DeviceCatalog
WHERE [UniqueID] = #UniqueID;
UPDATE DeviceCatalog
SET [OS] = #OS
,[Location] = #Geo
,[Culture] = #Culture
,[Other] = #Other
,[IPAddress] = #IPAddress
WHERE [UniqueID] = #UniqueID;
IF (#OldGeo IS NULL OR #OldAddress IS NULL OR #OldCity IS NULL OR #OldCountry IS NULL OR ISNULL(#Geo.STDistance(#OldGeo) / 1000,0) > 50)
BEGIN
UPDATE DeviceCatalog
SET [Lastmodifieddate] = Getdate()
WHERE [UniqueID] = #UniqueID;
END
END
ELSE
BEGIN
INSERT INTO DeviceCatalog
([OS]
,[UniqueID]
,[Location]
,[Culture]
,[Other]
,[IPAddress]
,[NativeDeviceID])
VALUES (#OS
,#UniqueID
,#Geo
,#Culture
,#Other
,#IPAddress
,#NativeDeviceID);
IF(#OldUniqueID != ''-1'' AND #OldUniqueID != #UniqueID)
BEGIN
EXEC DeleteOldAndroidDeviceID #OldUniqueID, #UniqueID;
END
END
LBEXIT:
IF #TranCount = 0
COMMIT;
END TRY
BEGIN CATCH
DECLARE #Error INT, #Message VARCHAR(4000), #XState INT;
SELECT #Error = ERROR_NUMBER() ,#Message = ERROR_MESSAGE() ,#XState = XACT_STATE();
IF #XState = -1
ROLLBACK;
IF #XState = 1 AND #TranCount = 0
rollback
IF #XState = 1 AND #TranCount > 0
ROLLBACK TRANSACTION Insertorupdatedevicecatalog;
RAISERROR (''Insertorupdatedevicecatalog: %d: %s'', 16, 1, #error, #message) ;
END CATCH
END
The timeout occurs due to two updates to same table inside same transaction. You could avoid it with a case statement. Also whole IF ELSE can be replaced with a merge.
MERGE INTO DeviceCatalog DC
USING (SELECT #UniqueID AS UniqueID) T ON (DC.UniqueID = T.UniqueID)
WHEN MATCHED THEN
UPDATE SET [OS] = #OS
,[Location] = #Geo
,[Culture] = #Culture
,[Other] = #Other
,[IPAddress] = #IPAddress
,[Lastmodifieddate] = (CASE
WHEN (LastUpdatedLocationFromJob IS NULL OR [Address] IS NULL OR [City] IS NULL OR [Country] IS NULL OR ISNULL(#Geo.STDistance(LastUpdatedLocationFromJob) / 1000,0) > 50)
THEN Getdate()
ELSE [Lastmodifieddate]
END)
WHEN NOT MATCHED THEN
INSERT INTO DeviceCatalog
([OS]
,[UniqueID]
,[Location]
,[Culture]
,[Other]
,[IPAddress]
,[NativeDeviceID])
VALUES (#OS
,#UniqueID
,#Geo
,#Culture
,#Other
,#IPAddress
,#NativeDeviceID)
WHEN NOT MATCHED BY SOURCE AND #OldUniqueID != ''-1'' AND #OldUniqueID != #UniqueID THEN
DELETE;
Try it and check whether this is what you expected.
Already discussed here
You can achieve it using sp_getapplock in TSQL.
But you need a wrapper storedproc or batch for this. Check the following example it will help you to desing your wrapper sp/batch statement.
Sample Code Snippet
Create table MyTable
(
RowId int identity(1,1),
HitStartedAt datetime,
HitTimestamp datetime,
UserName varchar(100)
)
Go
Create proc LegacyProc (#user varchar(100), #CalledTime datetime)
as
Begin
Insert Into MyTable
Values(#CalledTime, getdate(), #user);
--To wait for 10 sec : not required for your procedures, producing the latency to check the concurrent users action
WAITFOR DELAY '000:00:10'
End
Go
Create Proc MyProc
(
#user varchar(100)
)
as
Begin
Declare #PorcName as NVarchar(1000), #CalledTime datetime
Begin Tran
--To get the Current SP Name, it should be unique for each SP / each batch
SET #PorcName = object_name(##ProcID)
SET #CalledTime = Getdate()
--Lock the Current Proc
Exec sp_getapplock #Resource = #PorcName, #LockMode = 'Exclusive'
--Execute Your Legacy Procedures
Exec LegacyProc #user, #CalledTime
--Release the lock
Exec sp_releaseapplock #Resource = #PorcName
Commit Tran
End
You are doing two seperate updates on the DeviceCatalog table where [UniqueID] = #UniqueID in the same transaction.
I bet your locking/request timeout issue is happening when:
IF (#OldGeo IS NULL OR #OldAddress IS NULL OR #OldCity IS NULL OR #OldCountry IS NULL OR ISNULL(#Geo.STDistance(#OldGeo) / 1000,0) > 50) is true.
Try something like this in place of the two updates.
Obviously test in dev first.
In the else clause, you want to have it insert something if the when is false. Here I am just inserting the current before update field contents.
UPDATE DeviceCatalog
SET [OS] = #OS
,[Location] = #Geo
,[Culture] = #Culture
,[Other] = #Other
,[IPAddress] = #IPAddress
,[Lastmodifieddate] =
case when (
#OldGeo is NULL
OR
#OldAddress is NULL
OR
#OldCity is NULL
OR
#OldCountry is NULL
OR
ISNULL(#Geo.STDistance(#OldGeo) / 1000,0) > 50
) then Getdate()
else [Lastmodifieddate]
end
WHERE [UniqueID] = #UniqueID

The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction?

Hello Every One The Following Error Comes To Me Suddenly When I Changed Simple And Few Thing On My Stored Procedure Code And It Was Working Great And If I Cleared The Updated Code It Works Fine Again So I Do Not Know What Is The Reason
And Here Is The Error "The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction"
Thanks In Advance
ALTER Procedure [dbo].[xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx]
#English Bit = 0 ,
#ID BigInt = NULL Output ,
#Company_ID SmallInt = NULL ,
#Cust_ID NVarChar (20) = NULL ,
#Cust_Cat NVarChar (10) = NULL ,
#Debit_Limit Decimal (18,3) = NULL ,
#From_Date NVarChar (19) = NULL ,
#To_Date NVarChar (19) = NULL ,
#User_ID NVarChar(50) = NULL
As
BEGIN
Create Table #Errors (ErrorNumber int Not Null, ErrorValue nvarchar(300) Collate Arabic_CI_AS Null);
Begin Tran trn_INV_CustDebLim_setupInsert;
Begin Try
Insert Into INV_Cust_Debit_Limit_setup
( Company_ID , Cust_ID , Cust_Cat , Debit_Limit , From_Date , To_Date )
Values
( #Company_ID , #Cust_ID , #Cust_Cat , #Debit_Limit , #From_Date , #To_Date )
set #ID = ##IDENTITY
-- From Here Is New Part --
declare #str nvarchar(50)
IF(#Cust_ID IS NOT NULL)
set #str = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx ' + #Cust_ID
IF(#Cust_Cat IS NOT NULL)
set #str += 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx ' + #Cust_Cat
set #str += ' xxxxx' +#Debit_Limit + ' xxxx xx' +#From_Date
IF(#English = 1)
BEGIN
IF(#Cust_ID IS NOT NULL)
set #str = 'Credit Limit Added On Customer ' + #Cust_ID
IF(#Cust_Cat IS NOT NULL)
set #str += 'Credit Limit Added On Customer Category ' + #Cust_Cat
set #str = ' With Value ' +#Debit_Limit + ' From Date ' +#From_Date
END
exec usp_GLApplicationAudit #Company_ID , NULL , 10 , #User_ID , #str ,#ID ,10, NULL , NULL ,NULL ,NULL,NULL,'SAl'
-- To Here Is New Part --
End Try
Begin Catch
Insert #Errors Values(1002,ERROR_MESSAGE());
Goto Finished;
End Catch
-- Return Error Records
Finished:
-- retrieve Errors and commit/Rollbak Trans.
If (Select count(E.ErrorNumber)
From #Errors E Left Join GVT_Errors G
On E.ErrorNumber = G.Err_Number
Where G.Err_Type=0 ) > 0
Begin
-- The Following are Errors
Select E.ErrorNumber As [Err_No], G.MessageA + ': ' + E.ErrorValue As [Err_Desc], Err_Source, dbo.fn_GetItemDescription('Err_Type',Cast(Err_Type As nvarchar), null, null, null, null, 0) As Err_Type_Desc, Err_Type, SeverityLevel As [Severity], CategoryID
From #Errors E Left Join GVT_Errors G
On E.ErrorNumber = G.Err_Number;
Rollback Tran trn_INV_CustDebLim_setupInsert;
End
Else
Begin
-- The Following Not Errors They are Warnings or Information
Select E.ErrorNumber As [Err_No], G.MessageA + ': ' + E.ErrorValue As [Err_Desc], Err_Source, dbo.fn_GetItemDescription('Err_Type',Cast(Err_Type As nvarchar), null, null, null, null, 0) As Err_Type_Desc, Err_Type, SeverityLevel As [Severity], CategoryID
From #Errors E Left Join GVT_Errors G
On E.ErrorNumber = G.Err_Number;
Commit Tran trn_INV_CustDebLim_setupInsert;
End
DROP Table #Errors;
END
In the CATCH code you must check the state of XACT_STATE() and act accordingly. For a procedure template that handles transactions and try/catch blocks correctly see Exception Handling and Nested Transactions:
create procedure [usp_my_procedure_name]
as
begin
set nocount on;
declare #trancount int;
set #trancount = ##trancount;
begin try
if #trancount = 0
begin transaction
else
save transaction usp_my_procedure_name;
-- Do the actual work here
lbexit:
if #trancount = 0
commit;
end try
begin catch
declare #error int, #message varchar(4000), #xstate int;
select #error = ERROR_NUMBER(), #message = ERROR_MESSAGE(), #xstate = XACT_STATE();
if #xstate = -1
rollback;
if #xstate = 1 and #trancount = 0
rollback
if #xstate = 1 and #trancount > 0
rollback transaction usp_my_procedure_name;
raiserror ('usp_my_procedure_name: %d: %s', 16, 1, #error, #message) ;
end catch
end