मेरे पास एक संग्रहीत कार्यविधि है जिसे सम्मिलित-निष्पादन ब्लॉक में कहा जाता है:
insert into @t
exec('test')
मैं संग्रहीत प्रक्रिया में उत्पन्न अपवादों को कैसे संभाल सकता हूं और अभी भी प्रसंस्करण जारी रख सकता हूं?
निम्नलिखित कोड समस्या दिखाता है। आंतरिक exec()
कॉल की सफलता या विफलता के आधार पर मैं जो करना चाहता हूं वह 0 या -1 है।
alter procedure test -- or create
as
begin try
declare @retval int;
-- This code assumes that PrintMax exists already so this generates an error
exec('create procedure PrintMax as begin print ''hello world'' end;')
set @retval = 0;
select @retval;
return(@retval);
end try
begin catch
-- if @@TRANCOUNT > 0 commit;
print ERROR_MESSAGE();
set @retval = -1;
select @retval;
return(@retval);
end catch;
go
declare @t table (i int);
insert into @t
exec('test');
select *
from @t;
मेरी समस्या है return(-1)
। सफलता का रास्ता ठीक है।
यदि मैं संग्रहीत कार्यविधि में कोशिश / कैच ब्लॉक छोड़ देता हूं, तो त्रुटि उठाई जाती है और सम्मिलित विफल हो जाती है। हालांकि, मैं जो करना चाहता हूं वह है त्रुटि को संभालना और एक अच्छा मूल्य वापस करना।
संदेश के रूप में कोड है:
Msg 3930, Level 16, State 1, Line 6
The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction.
यह शायद सबसे खराब त्रुटि संदेश है जिसका मैंने सामना किया है। यह वास्तव में प्रतीत होता है "आप एक नेस्टेड लेनदेन में एक त्रुटि को संभाल नहीं पाए।"
अगर मैं अंदर डालता हूं if @@TRANCOUNT > 0
, तो मुझे संदेश मिलता है:
Msg 3916, Level 16, State 0, Procedure gordontest, Line 7
Cannot use the COMMIT statement within an INSERT-EXEC statement unless BEGIN TRANSACTION is used first.
मैंने शुरुआत / लेन-देन के बयानों के साथ खेलने की कोशिश की है, लेकिन कुछ भी काम नहीं करता है।
तो, समग्र लेनदेन को समाप्त किए बिना मैं अपनी संग्रहीत कार्यविधि को कैसे संभाल सकता हूं?
मार्टिन के जवाब में संपादित करें:
वास्तविक कॉलिंग कोड है:
declare @RetvalTable table (retval int);
set @retval = -1;
insert into @RetvalTable
exec('
@ घोषित करें int; exec @retval = '+ @ क्वेरी +'; @retval 'का चयन करें);
select @retval = retval from @RetvalTable;
@query
संग्रहित प्रक्रिया कॉल कहां है। संग्रहित प्रक्रिया से रिटर्न वैल्यू प्राप्त करना लक्ष्य है। यदि यह बिना insert
(या, विशेष रूप से, लेनदेन शुरू किए बिना) संभव है, तो यह बहुत अच्छा होगा।
मैं किसी तालिका में मान को संग्रहीत करने के लिए सामान्य रूप से संग्रहीत प्रक्रियाओं को संशोधित नहीं कर सकता, क्योंकि उनमें से बहुत सारे हैं। उनमें से एक विफल हो रहा है, और मैं इसे संशोधित कर सकता हूं। मेरा वर्तमान सबसे अच्छा समाधान कुछ इस तरह है:
if (@StoredProcedure = 'sp_rep__post') -- causing me a problem
begin
exec @retval = sp_rep__post;
end;
else
begin
-- the code I'm using now
end;
select @retval; return @retval
वह अंत में अधिक पसंद है । यदि आप डायनामिक संग्रहित प्रक्रिया कॉल से रिटर्न वैल्यू प्राप्त करने का एक और तरीका जानते हैं, तो मुझे जानना अच्छा लगेगा।
DECLARE @RC INT;EXEC sp_executesql N'EXEC @RC = test', N'@RC INT OUTPUT', @RC = @RC OUTPUT;insert into @t VALUES (@RC)
declare @t table (i int);declare @RC int;exec @RC = test;insert into @t values (@RC);select * from @t;
ठीक काम करता है।