SQL सर्वर संस्करण के आधार पर RAISERROR या THROW चुनना संभव है?


11

यहाँ मेरा कोड अभी है:

BEGIN TRY
INSERT INTO TABLE (F1,F2,F3) 
VALUES ('1','2','3')
END TRY
BEGIN CATCH
;THROW
END CATCH

महान काम करता है, जब तक कि यह SQL 2008 के साथ एक मशीन पर नहीं चलता है। मैं चाहूंगा कि CATCH ब्लॉक SQL वर्जन के खिलाफ चेक करे और THROW चलाए अगर यह 2012 के बराबर या इससे अधिक है, और RAISERROR अगर यह 2008 का है। सिंटैक्स त्रुटियां, और मैं सोच रहा हूं कि क्या यह संभव है। यहां तक ​​कि इस तरह से कुछ सरल मेरे लिए काम नहीं कर रहा है।

BEGIN CATCH
IF ((SELECT SERVERPROPERTY('productversion')) >= 11) ;THROW
END CATCH

किसी भी सलाह की सराहना की है।

जवाबों:


9

नहीं, यह संभव नहीं है।

यह पहले के संस्करणों में अमान्य सिंटैक्स है और एक संकलित त्रुटि का कारण होगा।

इसे छिपाने के लिए संभव नहीं है THROWएक में EXECके रूप में एक parameterless फेंक सीधे पकड़ अंदर निहित किया जाना चाहिए कैच ब्लॉक के अंदर या तो।

आपको उस SQL ​​सर्वर के संस्करण के अनुसार इच्छित कोड संस्करण परिनियोजित करने की आवश्यकता होगी जिसे आप परिनियोजित कर रहे हैं (और दुर्भाग्य से इसके लिए कोई अच्छा समर्थन नहीं है SSDT टूलींग में जो मुझे ज्ञात है - कोई भी समतुल्य कोड पंक्तियों को चुनिंदा रूप से शामिल नहीं करता है सशर्त संकलन)


4

यह इंगित किया जाना चाहिए कि, भले ही यह तकनीकी रूप से संभव हो , के बीच वैकल्पिक करने के लिए THROWऔर RAISERROR, आप (सबसे अधिक संभावना) वास्तव में ऐसा नहीं करना चाहेंगे। क्यों? क्योंकि parameterless की बहुत गंधा क्षमता THROWकरने के लिए त्रुटि का उपयोग कर फिर से फेंक एक ही संदेश संख्या (यानी Msg 8134बजाय Msg Xजहां X> = 50000) उन दोनों के बीच फर्क सिर्फ इतना नहीं है: THROWहै बैच-निरस्त किया जा रहा है, जबकि RAISERRORनहीं है। यह नीचे दिखाए गए अनुसार एक महत्वपूर्ण व्यवहारगत अंतर हो सकता है।

परीक्षण व्यवस्था

--DROP PROC ##Throw;
--DROP PROC ##RaisError;

GO
CREATE PROCEDURE ##Throw
AS
SET NOCOUNT ON;
BEGIN TRY
  SELECT 1/0 AS [DivideByZero];
END TRY
BEGIN CATCH
  THROW;
END CATCH;
SELECT 1 AS [AA];
GO

CREATE PROCEDURE ##RaisError
AS
SET NOCOUNT ON;
BEGIN TRY
  SELECT 1/0 AS [DivideByZero];
END TRY
BEGIN CATCH
  RAISERROR('test, yo!', 16, 1);
  -- RETURN; -- typically at end of CATCH block when using RAISERROR
END CATCH;
SELECT 2 AS [BB];
GO

परीक्षण 1

EXEC ##Throw;
SELECT 3 AS [CC];

यह दिखाता है:

"Results" Tab:

DivideByZero
{empty result set}

"Messages" Tab:

Msg 8134, Level 16, State 1, Procedure ##Throw, Line 38
Divide by zero error encountered.

परीक्षण २

EXEC ##RaisError;
SELECT 4 AS [DD];

यह दिखाता है:

"Results" Tab:

DivideByZero
{empty result set}

BB
2

DD
4

"Messages" Tab:

Msg 50000, Level 16, State 1, Procedure ##RaisError, Line 45
test, yo!

निष्पक्ष होने के लिए, इस अंतर को निम्नलिखित रूप से पूरा करना संभव है:

  • हमेशाTHROW एक TRY...CATCHनिर्माण के भीतर कोड का उपयोग करके सभी कॉल लपेटें (नीचे प्रदर्शित किया गया है)
  • कोड को कभी भी THROW( प्लेस को छोड़कर, इसके अलावा END CATCH;) न रखें

परीक्षण ३

BEGIN TRY
  EXEC ##Throw;
  SELECT 5 AS [EE];
END TRY
BEGIN CATCH
  SELECT ERROR_NUMBER() AS [ErrorNumber], ERROR_MESSAGE() AS [ErrorMessage];
END CATCH;
SELECT 6 AS [FF];
GO

यह दिखाता है:

"Results" Tab:

DivideByZero
{empty result set}

ErrorNumber     ErrorMessage
8134            Divide by zero error encountered.

FF
6

परीक्षण ४

BEGIN TRY
  EXEC ##RaisError;
  SELECT 7 AS [GG];
END TRY
BEGIN CATCH
  SELECT ERROR_NUMBER() AS [ErrorNumber], ERROR_MESSAGE() AS [ErrorMessage];
END CATCH;
SELECT 8 AS [HH];
GO

यह दिखाता है:

"Results" Tab:

DivideByZero
{empty result set}

ErrorNumber     ErrorMessage
50000           test, yo!

HH
8

3

मेरा मानना ​​है कि मार्टिन स्मिथ का जवाब लगभग 100% सही है।

ऐसा करने का एकमात्र तरीका डायनेमिक SQL के साथ है, और आपको अपने सभी प्रयास / कैच ब्लॉक (या यदि आप सभी के दो संस्करण करने जा रहे हैं, तो पूरी प्रक्रिया बनाएं स्टेटमेंट को रैप करके अपने कोड की एक बड़ी मात्रा को डुप्लिकेट करना होगा) उन) जो संस्करण के आधार पर निष्पादित होते हैं।

यह बनाए रखने के लिए एक बुरा सपना होगा। यह मत करो।

क्या SQL सर्वर संस्करण पर आधारित SQL कथन को निष्पादित करने का एक तरीका है?

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.