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

IN सूची में मौजूद तत्वों के लिए भी रिटर्निंग परिणाम जो तालिका में मौजूद नहीं हैं

SQL पक्ष से आप एक तालिका प्रकार को परिभाषित कर सकते हैं और इसका उपयोग अपने वास्तविक डेटा में शामिल होने के लिए कर सकते हैं, कुछ इस तरह:

create type my_array_type as table of number
/

create or replace function f42 (in_array my_array_type)
return sys_refcursor as
  rc sys_refcursor;
begin
  open rc for
    select a.column_value as id,
      case when t.id is null then 'missing'
        else 'present' end as status
    from table(in_array) a
    left join t42 t on t.id = a.column_value
    order by id;

  return rc;
end f42;
/

SQL Fiddle डेमो एक रैपर फ़ंक्शन के साथ ताकि आप इसे सीधे क्वेरी कर सकें, जो देता है:

        ID STATUS             
---------- --------------------
         1 present              
         2 present              
         3 present              
         4 missing              
         8 missing              
        23 present              

जावा से आप एक ARRAY परिभाषित कर सकते हैं तालिका प्रकार के आधार पर, जावा सरणी से पॉप्युलेट करें, और फ़ंक्शन को सीधे कॉल करें; आपका सिंगल पैरामीटर बाइंड वैरिएबल ARRAY है , और आपको एक परिणाम सेट वापस मिलता है जिसे आप सामान्य रूप से पुनरावृत्त कर सकते हैं।

जावा पक्ष की रूपरेखा के रूप में:

int[] ids = { 1, 2, 3, 4, 8, 23 };
ArrayDescriptor aDesc = ArrayDescriptor.createDescriptor("MY_ARRAY_TYPE",
  conn);
oracle.sql.ARRAY ora_ids = new oracle.sql.ARRAY(aDesc, conn, ids);

cStmt = (OracleCallableStatement) conn.prepareCall("{ call ? := f42(?) }");
cStmt.registerOutParameter(1, OracleTypes.CURSOR);
cStmt.setArray(2, ora_ids);
cStmt.execute();
rSet = (OracleResultSet) cStmt.getCursor(1);

while (rSet.next())
{
    System.out.println("id " + rSet.getInt(1) + ": " + rSet.getString(2));
}

जो देता है:

id 1: present
id 2: present
id 3: present
id 4: missing
id 8: missing
id 23: present

जैसा कि महेश्वरन रविशंकर ने उल्लेख किया है, यह किसी भी संख्या में तत्वों को पारित करने की अनुमति देता है; आपको यह जानने की आवश्यकता नहीं है कि संकलन समय पर कितने तत्व हैं (या सैद्धांतिक अधिकतम से निपटें), आप IN में अनुमत अभिव्यक्तियों की अधिकतम संख्या तक सीमित नहीं हैं या एकल सीमांकित स्ट्रिंग की लंबाई के अनुसार, और आपको एकाधिक मानों को पास करने के लिए स्ट्रिंग को बनाने और विघटित करने की आवश्यकता नहीं है।

जैसा कि थिंकजेट ने बताया, यदि आप अपना स्वयं का टेबल प्रकार नहीं बनाना चाहते हैं तो आप यहां प्रदर्शित पूर्वनिर्धारित संग्रह का उपयोग कर सकते हैं; पैरामीटर की घोषणा के अलावा मुख्य कार्य समान है:

create or replace function f42 (in_array sys.odcinumberlist)
return sys_refcursor as
...    

रैपर फ़ंक्शन सरणी को थोड़ा अलग तरीके से पॉप्युलेट करता है, लेकिन जावा पक्ष पर आपको केवल इस पंक्ति को बदलने की आवश्यकता है:

ArrayDescriptor aDesc =
  ArrayDescriptor.createDescriptor("SYS.ODCINUMBERLIST", conn );

इसका उपयोग करने का अर्थ यह भी है (जैसा कि थिंकजेट ने भी बताया!) कि आप किसी फ़ंक्शन को परिभाषित किए बिना अपनी मूल स्टैंड-अलोन क्वेरी चला सकते हैं:

select a.column_value as id,
case when t.id is null then 'missing'
else 'present' end as status
from table(sys.odcinumberlist(1, 2, 3, 4, 8, 23)) a
left join t42 t on t.id = a.column_value
order by id;

(एसक्यूएल फिडल)।

और इसका मतलब है कि आप सीधे जावा से क्वेरी को कॉल कर सकते हैं:

int[] ids = { 1, 2, 3, 4, 8, 23 };
ArrayDescriptor aDesc = ArrayDescriptor.createDescriptor("SYS.ODCINUMBERLIST", conn );
oracle.sql.ARRAY ora_ids = new oracle.sql.ARRAY(aDesc, conn, ids);

sql = "select a.column_value as id, "
    + "case when t.id is null then 'missing' "
    + "else 'present' end as status "
    + "from table(?) a "
    + "left join t42 t on t.id = a.column_value "
    + "order by id";
pStmt = (OraclePreparedStatement) conn.prepareStatement(sql);
pStmt.setArray(1, ora_ids);
rSet = (OracleResultSet) pStmt.executeQuery();

while (rSet.next())
{
    System.out.println("id " + rSet.getInt(1) + ": " + rSet.getString(2));
}

... जिसे आप पसंद कर सकते हैं।

एक पूर्व-निर्धारित ODCIVARCHAR2LIST है टाइप भी करें, यदि आप वास्तव में स्ट्रिंग्स पास कर रहे हैं - ऐसा लगता है कि आपका मूल कोड स्ट्रिंग्स के साथ काम कर रहा है, भले ही उनमें संख्याएं हों, इसलिए सुनिश्चित नहीं है कि आपको वास्तव में किसकी आवश्यकता है।

क्योंकि इन प्रकारों को VARRAY(32767) . के रूप में परिभाषित किया गया है आप 32k मानों तक सीमित हैं, जबकि अपनी स्वयं की तालिका को परिभाषित करने से वह प्रतिबंध हटा दिया जाता है; लेकिन स्पष्ट रूप से यह तभी मायने रखता है जब आप बहुत सारे मूल्यों को पारित कर रहे हों।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle में 10 मिनट के भीतर 10 मिलियन प्रश्नों का INSERT?

  2. Oracle PL/SQL संग्रह - मौजूदा तालिका में तत्वों को जोड़ना

  3. ORA-01438:3 . डालने पर इस कॉलम के लिए अनुमत निर्दिष्ट सटीकता से बड़ा मान

  4. Oracle Concatenate स्ट्रिंग और संख्या उदाहरण

  5. oracle11g . में पैरामीटरयुक्त दृश्य बनाना