Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

क्या CASE स्टेटमेंट और DECODE समकक्ष हैं?

संक्षिप्त उत्तर, नहीं।

थोड़ा लंबा उत्तर लगभग है।

यह केवल प्रकट होता है कि प्रत्येक कथन से प्राप्त परिणाम समान है। यदि हम लौटाए गए डेटा प्रकारों का मूल्यांकन करने के लिए DUMP फ़ंक्शन का उपयोग करते हैं, तो आप देखेंगे कि मेरा क्या मतलब है:

SQL> select dump(case 1 when 2 then null else 0 end) as simple_case
  2       , dump(case when 1 = 2 then null else 0 end) as searched_case
  3       , dump(decode(1, 2, null, 0)) as decode
  4    from dual;

SIMPLE_CASE        SEARCHED_CASE      DECODE
------------------ ------------------ -----------------
Typ=2 Len=1: 128   Typ=2 Len=1: 128   Typ=1 Len=1: 48

एसक्यूएल फिडल

आप देख सकते हैं कि DECODE का डेटा प्रकार 1 है, जबकि दो CASE स्टेटमेंट "रिटर्न" डेटा प्रकार 2 का है। Oracle के डेटा प्रकार सारांश का उपयोग करते हुए, DECODE एक VARCHAR2 (डेटा प्रकार 1) लौटा रहा है, जबकि CASE स्टेटमेंट "रिटर्निंग" हैं। "संख्याएं (डेटा प्रकार 2)।

मुझे लगता है कि ऐसा इसलिए होता है क्योंकि, जैसा कि नाम से पता चलता है, DECODE एक फ़ंक्शन है और CASE नहीं है, जिसका अर्थ है कि उन्हें आंतरिक रूप से अलग तरीके से लागू किया गया है। इसे साबित करने का कोई वास्तविक तरीका नहीं है।

आप सोच सकते हैं कि यह वास्तव में कुछ भी प्रभावित नहीं करता है। यदि आपको एक संख्या होने की आवश्यकता है तो ओरेकल निहित रूपांतरण नियमों के तहत चरित्र को एक संख्या में बदल देगा, है ना? यह भी सच नहीं है, यह यूनियन में काम नहीं करेगा क्योंकि डेटा प्रकार है समान होना; Oracle आपके लिए चीजों को आसान बनाने के लिए कोई अंतर्निहित रूपांतरण नहीं करेगा। दूसरे, यहां बताया गया है कि Oracle निहित रूपांतरण के बारे में क्या कहता है:

<ब्लॉकक्वॉट>

Oracle अनुशंसा करता है कि आप इन कारणों से निहित या स्वचालित रूपांतरणों पर भरोसा करने के बजाय स्पष्ट रूपांतरण निर्दिष्ट करें:

  • जब आप स्पष्ट डेटा प्रकार रूपांतरण फ़ंक्शन का उपयोग करते हैं तो SQL कथनों को समझना आसान होता है।

  • निहित डेटा प्रकार रूपांतरण का प्रदर्शन पर नकारात्मक प्रभाव पड़ सकता है, खासकर यदि किसी स्तंभ मान का डेटा प्रकार किसी अन्य तरीके से स्थिरांक में परिवर्तित हो जाता है।

  • निहित रूपांतरण उस संदर्भ पर निर्भर करता है जिसमें यह होता है और हर मामले में एक ही तरह से काम नहीं कर सकता है। उदाहरण के लिए, डेटाटाइम मान से VARCHAR2 मान में निहित रूपांतरण NLS_DATE_FORMATपैरामीटर के मान के आधार पर एक अप्रत्याशित वर्ष लौटा सकता है।

  • निहित रूपांतरण के लिए एल्गोरिदम सॉफ़्टवेयर रिलीज़ और Oracle उत्पादों के बीच परिवर्तन के अधीन हैं। स्पष्ट रूपांतरणों का व्यवहार अधिक अनुमानित होता है।

यह एक सुंदर सूची नहीं है; लेकिन अंतिम बिंदु मुझे तारीखों पर अच्छी तरह से लाता है। यदि हम पिछली क्वेरी को लेते हैं और उसे एक में परिवर्तित करते हैं जो इसके बजाय एक तिथि का उपयोग करता है:

select case sysdate when trunc(sysdate) then null 
                    else sysdate 
       end as simple_case
     , case when sysdate = trunc(sysdate) then null 
            else sysdate 
       end as searched_case
     , decode(sysdate, trunc(sysdate), null, sysdate) as decode
  from dual;

एक बार फिर, इस क्वेरी पर DUMP का उपयोग करते हुए CASE स्टेटमेंट डेटा टाइप 12, एक DATE को लौटाते हैं। DECODE ने sysdate . को रूपांतरित कर दिया है एक VARCHAR2 में।

SQL> select dump(case sysdate when trunc(sysdate) then null
  2                           else sysdate
  3              end) as simple_case
  4       , dump(case when sysdate = trunc(sysdate) then null
  5                   else sysdate
  6              end) as searched_case
  7       , dump(decode(sysdate, trunc(sysdate), null, sysdate)) as decode
  8    from dual;

SIMPLE_CASE          
---------------------------------- 
Typ=12 Len=7: 120,112,12,4,22,18,7 
SEARCHED_CASE
---------------------------------- 
Typ=12 Len=7: 120,112,12,4,22,18,7
DECODE
---------------------------------- 
Typ=1 Len=19: 50,48,49,50,45,49,50,45,48,52,32,50,49,58,49,55,58,48,54

एसक्यूएल फिडल

नोट (एसक्यूएल फिडल में) कि DATE को NLS_DATE_FORMAT सत्रों का उपयोग करके एक वर्ण में बदल दिया गया है।

एक तिथि होने से जिसे स्पष्ट रूप से VARCHAR2 में परिवर्तित कर दिया गया है, समस्याएं पैदा कर सकता है। यदि आप अपनी तिथि को एक वर्ण में बदलने के लिए TO_CHAR का उपयोग करने का इरादा रखते हैं, तो आपकी क्वेरी वहां टूट जाएगी जहां आप इसकी अपेक्षा नहीं कर रहे हैं।

SQL> select to_char( decode( sysdate
  2                         , trunc(sysdate), null
  3                         , sysdate )
  4                 , 'yyyy-mm-dd') as to_char
  5    from dual;
select to_char( decode( sysdate
                *
ERROR at line 1:
ORA-01722: invalid number

एसक्यूएल फिडल

समान रूप से, तिथि अंकगणित अब काम नहीं करता:

SQL>
SQL>
SQL> select decode(sysdate, trunc(sysdate), null, sysdate) + 1 as decode
  2    from dual;
select decode(sysdate, trunc(sysdate), null, sysdate) + 1 as decode
       *
ERROR at line 1:
ORA-01722: invalid number

एसक्यूएल फिडल

दिलचस्प रूप से DECODE केवल अभिव्यक्ति को VARCHAR2 में परिवर्तित करता है यदि संभावित परिणामों में से एक NULL है। यदि डिफ़ॉल्ट मान NULL है तो ऐसा नहीं होता है। उदाहरण के लिए:

SQL> select decode(sysdate, sysdate, sysdate, null) as decode
  2    from dual;

DECODE
-------------------
2012-12-04 21:18:32

SQL> select dump(decode(sysdate, sysdate, sysdate, null)) as decode
  2    from dual;

DECODE
------------------------------------------    
Typ=13 Len=8: 220,7,12,4,21,18,32,0

एसक्यूएल फिडल

ध्यान दें कि DECODE ने 13 का डेटा प्रकार लौटाया है। यह प्रलेखित नहीं है, लेकिन मुझे लगता है, दिनांक अंकगणित आदि के रूप में एक प्रकार की तारीख काम करती है।

संक्षेप में, यदि संभव हो तो DECODE से बचें; हो सकता है कि आपको वह डेटा प्रकार न मिले जिसकी आप अपेक्षा कर रहे हैं। टॉम कायटे को उद्धृत करने के लिए:

<ब्लॉकक्वॉट>

डिकोड कुछ हद तक अस्पष्ट है - मामला बहुत स्पष्ट है। जो चीजें डिकोड में करना आसान है वे CASE में करना आसान है, जो चीजें कठिन हैं या डिकोड के साथ करना असंभव है वे CASE में करना आसान है। केस, तार्किक रूप से, जीत जाता है।

बस पूरा होने के लिए दो कार्यात्मक हैं DECODE और CASE के बीच अंतर।

  1. DECODE का उपयोग PL/SQL में नहीं किया जा सकता।
  2. सीधे नल की तुलना करने के लिए CASE का उपयोग नहीं किया जा सकता है

    SQL> select case null when null then null else 1 end as case1
      2        , case when null is null then null else 1 end as case2
      3        , decode(null, null, null, 1) as decode
      4    from dual
      5         ;
    
         CASE1      CASE2 DECODE
    ---------- ---------- ------
             1
    

    एसक्यूएल फिडल



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ORA-12560:TNS:प्रोटोकॉल एडेप्टर त्रुटि

  2. Oracle VM Virtual Box के साथ एक वर्चुअल मशीन बनाना

  3. डेटाबेस कॉन्फ़िगरेशन सहायक का उपयोग करके Oracle 12c के लिए नमूना स्कीमा स्थापित करना

  4. Oracle में XLSX (एक्सेल) फ़ाइल पढ़ें और आयात करें

  5. एक्सेल वर्कशीट में Oracle टेबल एक्सपोर्ट करना