কেন লিঙ্কযুক্ত সার্ভারের কোনও CASE এক্সপ্রেশনটিতে 10 টি শাখার সীমাবদ্ধতা রয়েছে?


19

কেন এই CASEঅভিব্যক্তি:

SELECT CASE column 
        WHEN 'a' THEN '1' 
        WHEN 'b' THEN '2' 
        ... c -> i
        WHEN 'j' THEN '10' 
        WHEN 'k' THEN '11'  
    END [col] 
FROM LinkedServer.database.dbo.table

এই ফলাফল উত্পাদন?

ত্রুটির বার্তা: এমএসজি 8180, স্তর 16, রাজ্য 1, লাইন 1
বিবৃতি প্রস্তুত করা যায়নি।
এমএসজি 125, স্তর 15, রাজ্য 4, লাইন 1
কেস এক্সপ্রেশন কেবল মাত্র 10 স্তরে নেস্ট করা যেতে পারে।

স্পষ্টতই CASEএখানে নেস্টেড এক্সপ্রেশন নেই, যদিও এখানে 10 টিরও বেশি "শাখা" রয়েছে।

আরেকটি বিজোড়তা। এই ইনলাইন টেবিল-মূল্যযুক্ত ফাংশনটি একই ত্রুটি তৈরি করে:

ALTER FUNCTION [dbo].[fn_MyFunction]
(   
     @var varchar(20)
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT CASE column 
            WHEN 'a' THEN '1' 
            WHEN 'b' THEN '2' 
            ... c -> i
            WHEN 'j' THEN '10' 
            WHEN 'k' THEN '11'  
        END [col] 
    FROM LinkedServer.database.dbo.table
)

তবে অনুরূপ একটি বহু-বিবৃতি টিভিএফ কাজ করে:

ALTER FUNCTION [dbo].[fn_MyFunction]
(   
    @var varchar(20)
)
RETURNS @result TABLE 
(
    value varchar(max)
)
AS
BEGIN
    INSERT INTO @result
    SELECT CASE column 
            WHEN 'a' THEN '1' 
            WHEN 'b' THEN '2' 
            ... c -> i
            WHEN 'j' THEN '10' 
            WHEN 'k' THEN '11'  
        END [col] 
    FROM LinkedServer.database.dbo.table

RETURN;
END

উত্তর:


24

স্পষ্টতই CASEএখানে নেস্টেড এক্সপ্রেশন নেই।

কোয়েরি পাঠ্যে নেই, না। তবে পার্সার সর্বদা CASEনেস্টেড ফর্মের কাছে এক্সপ্রেশনগুলি প্রসারিত করে:

SELECT CASE SUBSTRING(p.Name, 1, 1)
        WHEN 'a' THEN '1' 
        WHEN 'b' THEN '2' 
        WHEN 'c' THEN '3' 
        WHEN 'd' THEN '4' 
        WHEN 'e' THEN '5' 
        WHEN 'f' THEN '6' 
        WHEN 'g' THEN '7' 
        WHEN 'h' THEN '8' 
        WHEN 'i' THEN '9' 
        WHEN 'j' THEN '10' 
        WHEN 'k' THEN '11'  
    END
FROM AdventureWorks2012.Production.Product AS p

স্থানীয় জিজ্ঞাসা পরিকল্পনা

এই ক্যোয়ারীটি স্থানীয় (কোনও লিঙ্কযুক্ত সার্ভার নয়) এবং কম্পিউট স্কেলার নিম্নলিখিত বর্ণনাকে সংজ্ঞায়িত করে:

নেস্টেড CASE এক্সপ্রেশন

স্থানীয়ভাবে মৃত্যুদন্ড কার্যকর করার সময় এটি ঠিক আছে, কারণ পার্সারCASE 10 স্তরের গভীর নীচে নেস্টেড স্টেটমেন্ট দেখতে পাবে না (যদিও এটি স্থানীয় ক্যোয়ারী সংকলনের পরবর্তী পর্যায়ে পৌঁছায়)।

তবে কোনও লিঙ্কযুক্ত সার্ভারের সাথে, উত্পন্ন পাঠ্যটি সংকলনের জন্য দূরবর্তী সার্ভারে প্রেরণ করা যেতে পারে। যদি এটি হয় তবে দূরবর্তী পার্সারCASE 10 স্তরেরও বেশি গভীর নেস্টেড বিবৃতি দেখতে পাবে এবং আপনি ত্রুটি 8180 পেয়ে যাবেন।

আরেকটি বিজোড়তা। এই ইনলাইন টেবিল-মূল্যযুক্ত ফাংশন একই ত্রুটি উত্পাদন করে

মূল-ক্যোরির পাঠ্যে ইন-লাইন ফাংশনটি স্থান-স্থলে প্রসারিত করা হয়েছে, সুতরাং লিংকযুক্ত সার্ভারের সাথে একই ত্রুটির ফলাফলের ফলে অবাক হওয়ার কিছু নেই।

তবে অনুরূপ একটি বহু-বিবৃতি টিভিএফ কাজ করে

অনুরূপ, তবে একই নয়। এমএসটিভিএফ-এ একটি অন্তর্নিহিত রূপান্তর জড়িত varchar(max), যা CASEরিমোট সার্ভারে এক্সপ্রেশনটি প্রেরণ করা রোধ করতে ঘটে । CASEস্থানীয়ভাবে মূল্যায়ন করা হয় বলে কোনও পার্সার কখনই অতি-নেস্টেড দেখতে পায় না CASEএবং কোনও ত্রুটি নেই। আপনি যদি ফলাফলের varchar(max)অন্তর্নির্মিত ধরণের থেকে টেবিল সংজ্ঞাটি পরিবর্তন করেন CASE- varchar(2)- এক্সপ্রেশনটি এমএসটিভিএফ দিয়ে সরিয়ে দেওয়া হয় এবং আপনি একটি ত্রুটি পাবেন।

শেষ পর্যন্ত, CASEদূরবর্তী সার্ভার দ্বারা একটি অতি-নেস্টেড মূল্যায়ন করা হলে ত্রুটি ঘটে । যদি CASEরিমোট ক্যোয়ারী পুনরুক্তি ব্যবস্থায় মূল্যায়ন না করা হয় তবে কোনও ত্রুটির ফলাফল নেই। উদাহরণস্বরূপ, নীচে এমন একটি অন্তর্ভুক্ত রয়েছে CONVERTযা প্রত্যাহারযোগ্য নয়, সুতরাং কোনও লিঙ্কযুক্ত সার্ভার ব্যবহৃত হলেও ত্রুটি ঘটে না:

SELECT CASE CONVERT(varchar(max), SUBSTRING(p.Name, 1, 1))
        WHEN 'a' THEN '1' 
        WHEN 'b' THEN '2' 
        WHEN 'c' THEN '3' 
        WHEN 'd' THEN '4' 
        WHEN 'e' THEN '5' 
        WHEN 'f' THEN '6' 
        WHEN 'g' THEN '7' 
        WHEN 'h' THEN '8' 
        WHEN 'i' THEN '9' 
        WHEN 'j' THEN '10' 
        WHEN 'k' THEN '11'  
    END
FROM SQL2K8R2.AdventureWorks.Production.Product AS p

CASE সরিয়ে নেই


6

আমার কুণ্ডলীটি হ'ল কোয়েরিটি কিছুটা আলাদা CASEকাঠামোর জন্য কোথাও আবার লেখা হচ্ছে , যেমন

CASE WHEN column = 'a' THEN '1' ELSE CASE WHEN column = 'b' THEN '2' ELSE ...

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

পল যেমন উল্লেখ করেছেন , এসকিউএল সার্ভার আপনার CASEঅভিব্যক্তিটিকে নীড়যুক্ত বিভিন্নতে প্রসারিত করছে , এবং লিঙ্কযুক্ত সার্ভারটি এটি পছন্দ করে না। ত্রুটি বার্তাটি বিভ্রান্তিকর, তবে কেবলমাত্র অভিব্যক্তির অন্তর্নিহিত রূপান্তরটি তাত্ক্ষণিকভাবে দৃশ্যমান নয় (কোনওভাবেই স্বজ্ঞাত নয়)।

একটি কাজ (আপনি নিজের প্রশ্নের সাথে যুক্ত ফাংশন পরিবর্তন ব্যতীত) হ'ল লিঙ্কযুক্ত সার্ভারে একটি ভিউ বা সংরক্ষণের পদ্ধতি তৈরি করতে পারেন এবং লিঙ্কযুক্ত সার্ভার সরবরাহকারীর মাধ্যমে সম্পূর্ণ কোয়েরিটি পাস করার পরিবর্তে উল্লেখ করা যেতে পারে।

আরেকটি (আপনার ক্যোয়ারীটি সত্যই ধরে নেওয়া এই সরলবাদী, এবং আপনি কেবলমাত্র অক্ষরের আজকের সংখ্যার সহগ চান) এইটি থাকতে হবে:

SELECT [col] = RTRIM(ASCII([column])-96)
FROM LinkedServer.database.dbo.table;

আপনার যদি প্রয়োজন ঠিক তেমন কাজ করার দরকার হয় তবে আমি আপনাকে সরাসরি সহায়তার সাথে যোগাযোগ করার এবং কেস খুলতে পরামর্শ দিই, যদিও আমি ফলাফলগুলি নিশ্চিত করতে পারি না - তারা কেবল আপনাকে এই পৃষ্ঠায় ইতিমধ্যে অ্যাক্সেসের মতো কাজের সুযোগ প্রদান করতে পারে।


5

আপনি এটি কাছাকাছি পেতে পারেন

SELECT COALESCE(
CASE SUBSTRING(p.Name, 1, 1)
    WHEN 'a' THEN '1' 
    WHEN 'b' THEN '2' 
    WHEN 'c' THEN '3' 
    WHEN 'd' THEN '4' 
    WHEN 'e' THEN '5' 
    WHEN 'f' THEN '6' 
    WHEN 'g' THEN '7' 
    WHEN 'h' THEN '8' 
    WHEN 'i' THEN '9' 
    ELSE NULL
END,
CASE SUBSTRING(p.Name, 1, 1)
    WHEN 'j' THEN '10' 
    WHEN 'k' THEN '11'  
END)
FROM SQL2K8R2.AdventureWorks.Production.Product AS p

2

এই সমস্যার জন্য আরেকটি কর্মসূচী হ'ল সেট ভিত্তিক যুক্তি ব্যবহার করা, CASEএকটি রেফারেন্স টেবিলের (বা refনীচের কোডে) বাম জোড় (বা বাইরের প্রয়োগ) দ্বারা অভিব্যক্তিটি প্রতিস্থাপন করা , যা স্থায়ী, অস্থায়ী বা উত্পন্ন টেবিল / সিটিই হতে পারে। যদি একাধিক প্রশ্ন এবং পদ্ধতিতে এটির প্রয়োজন হয় তবে আমি এটি স্থায়ী টেবিল হিসাবে পছন্দ করতাম:

SELECT ref.result_column AS [col] 
FROM LinkedServer.database.dbo.table AS t
  LEFT JOIN
    ( VALUES ('a',  '1'),
             ('b',  '2'), 
             ('c',  '3'),
             ---
             ('j', '10'),
             ('k', '11')
    ) AS ref (check_col, result_column) 
    ON ref.check_col = t.column ;

-4

এর কাছাকাছি যাওয়ার একটি উপায় হ'ল whenক্লজটিতে পরীক্ষা অন্তর্ভুক্ত করা ie

case
  when SUBSTRING(p.Name, 1, 1) = 'a' THEN '1'
...

আসলে না. উভয় SELECT CASE v.V WHEN 'a' THEN 1 WHEN 'b' THEN 2 END FROM (VALUES ('a'), ('b')) AS v (V);এবং SELECT CASE WHEN v.V = 'a' THEN 1 WHEN v.V = 'b' THEN 2 END FROM (VALUES ('a'), ('b')) AS v (V);অনুবাদ ঠিক একই ফাঁসি পরিকল্পনা (নিজের জন্য যে যাচাই করার জন্য বিনা দ্বিধায়), যেখানে ক্ষেত্রে অভিব্যক্তি হিসাবে পুনরায় সংজ্ঞায়িত করা হয় CASE WHEN [Union1002]='a' THEN (1) ELSE CASE WHEN [Union1002]='b' THEN (2) ELSE NULL END END- পাখির সঙ্গে, হিসাবে আপনি দেখতে পারেন।
অ্যান্ড্রি এম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.