এসকিউএল সার্ভার সংস্করণের উপর নির্ভর করে রাইজার বা থ্রো বেছে নেওয়া কি সম্ভব?


11

এই মুহূর্তে আমার কোড এখানে:

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

দুর্দান্ত কাজ করে, যদি না এটি এসকিউএল 2008 এর সাথে একটি মেশিনে চালিত হয় I'd সিনট্যাক্স ত্রুটিগুলি, এবং আমি এটি এমনকি সম্ভব কিনা তা ভাবছি। এমনকি এর মতো সাধারণ কিছু আমার পক্ষে কাজ করছে না।

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

কোন পরামর্শ প্রশংসা করা হয়।

উত্তর:


9

না এটি সম্ভব নয়।

এটি পূর্ববর্তী সংস্করণগুলিতে অবৈধ সিনট্যাক্স এবং একটি সংকলন ত্রুটির কারণ হবে।

প্যারামিটারলেস নিক্ষেপ সরাসরি ক্যাচের ভিতরে থাকা উচিত বলেই ক্যাচ ব্লকের অভ্যন্তরে THROWকোনও লুকানো সম্ভব নয় isEXEC

এসকিউএল সার্ভারের যে সংস্করণটি আপনি নিযুক্ত করছেন সে অনুযায়ী আপনার যে কোড সংস্করণটি চান তা আপনাকে মোতায়েন করতে হবে (এবং দুর্ভাগ্যক্রমে এসএসডিটি টুলিংয়ে এটি সম্পর্কে ভাল সমর্থন নেই - যা নির্বাচিতভাবে কোড লাইন অন্তর্ভুক্ত করার সমতুল্য নয়) শর্তসাপেক্ষ সংকলন)


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.

পরীক্ষা 2

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;)

পরীক্ষা 3

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

পরীক্ষা 4

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% সঠিক is

এটি করার একমাত্র উপায় হ'ল ডায়নামিক এসকিউএল সহ, এবং আপনার সমস্ত চেষ্টা / ক্যাপ ব্লককে আবৃত করে আপনার কোডের একটি বিশাল পরিমাণ নকল করতে হবে (বা যদি আপনার সমস্তটির দুটি সংস্করণ থাকে তবে সম্পূর্ণ বিবরণী বিবৃতি তৈরি করতে হবে) যারা) সংস্করণ উপর নির্ভর করে চালানো।

এটি বজায় রাখা দুঃস্বপ্ন হবে। এটা করবেন না।

এসকিউএল সার্ভার সংস্করণের উপর ভিত্তি করে এসকিউএল বিবৃতি কার্যকর করার কোনও উপায় আছে কি?

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.