Oracle PL / SQL - एक साधारण सरणी चर कैसे बनाएं?


128

मैं एक इन-मेमोरी एरे वेरिएबल बनाना चाहूंगा जिसका उपयोग मेरे पीएल / एसक्यूएल कोड में किया जा सकता है। मुझे Oracle PL / SQL में कोई संग्रह नहीं मिला है जो शुद्ध मेमोरी का उपयोग करता है, वे सभी तालिकाओं के साथ जुड़े हुए प्रतीत होते हैं। मैं अपने PL / SQL (C # सिंटैक्स) में ऐसा कुछ करना चाह रहा हूँ:

string[] arrayvalues = new string[3] {"Matt", "Joanne", "Robert"};

संपादित करें: Oracle: 9i



1
"तालिका" संदर्भ पुराने PL / SQL तालिकाओं के नामकरण से हैंगओवर हो जाता है। VARRAYs, एसोसिएटिव एरे और डिक्लेयरेड नेस्ट टेबल सभी इन-मेमोरी एरे टाइप हैं।
ओली

इस लिंक को पढ़ें orafaq.com/wiki/VARRAY और dba-oracle.com/tips_oracle_varray.htm
zloctb

जवाबों:


244

आप निश्चित आकार के सरणी के लिए वर का उपयोग कर सकते हैं:

declare
   type array_t is varray(3) of varchar2(10);
   array array_t := array_t('Matt', 'Joanne', 'Robert');
begin
   for i in 1..array.count loop
       dbms_output.put_line(array(i));
   end loop;
end;

या अनबाउंड सरणी के लिए टेबल:

...
   type array_t is table of varchar2(10);
...

शब्द "टेबल" यहां डेटाबेस तालिकाओं के साथ भ्रमित करने के लिए कुछ भी नहीं है। दोनों विधियाँ इन-मेमोरी एरेज़ बनाती हैं।

इनमें से किसी एक के साथ आपको तत्वों को जोड़ने से पहले संग्रह को शुरू करने और बढ़ाने की आवश्यकता है:

declare
   type array_t is varray(3) of varchar2(10);
   array array_t := array_t(); -- Initialise it
begin
   for i in 1..3 loop
      array.extend(); -- Extend it
      array(i) := 'x';
   end loop;
end;

पहला सूचकांक 1 नहीं 0 है।


75
"भ्रामक" सिर्फ ओरेकल के बारे में रकम
14:17 पर m.edmondson

क्या मैं सारणियों के समान तालिकाओं में सम्मिलित करता हूं? अर्थातmy_array(0) := 'some string';
अब्दुल

@TonyAndrews array.extend();क्या किसी नियमित बाउंड ऐरे में स्लॉट जोड़ सकता है? उस स्थिति में, यह पहले से ही आकार में गतिशील है, इसलिए तालिका (अनबाउंड सरणी) की आवश्यकता नहीं होगी।
अब्दुल

2
@ अब्दुल, नहीं, यह नहीं है। मैं कभी भी सामान्य रूप से VARRAY का उपयोग नहीं करता हूं लेकिन उपरोक्त कोड का परीक्षण करते समय मैंने जांच की कि क्या होता है यदि आप varray(3)4 बार विस्तार करने का प्रयास करते हैं - आपको "सीमा से बाहर" त्रुटि मिलती है।
टोनी एंड्रयूज

2
काश मैं इस सवाल का जवाब कई बार @TonyAndrews से देता, क्योंकि आपने कवर किया था array.extend()। हर जगह जहां मैंने देखा कि यह नहीं दिखा और यह एक से अधिक आइटम (मेरी समझ से, SQL में सरणियों के लिए अभी भी नया है) को जोड़ने में सक्षम होने के लिए सबसे महत्वपूर्ण हिस्सा था।
जोनाथन वैन डैम

61

आप BINARY_INTEGER द्वारा अनुक्रमित इन-मेमोरी चर लंबाई सरणी रखने के लिए बस DBMS_SQL.VARCHAR2_TABLE की घोषणा कर सकते हैं:

DECLARE
   name_array dbms_sql.varchar2_table;
BEGIN
   name_array(1) := 'Tim';
   name_array(2) := 'Daisy';
   name_array(3) := 'Mike';
   name_array(4) := 'Marsha';
   --
   FOR i IN name_array.FIRST .. name_array.LAST
   LOOP
      -- Do something
   END LOOP;
END;

जब आप इन-मेमोरी सरणी होते हैं, तो आप एक साहचर्य सरणी (जिसका उपयोग PL / SQL तालिकाओं के रूप में किया जाता है) कर सकते हैं।

DECLARE
   TYPE employee_arraytype IS TABLE OF employee%ROWTYPE
        INDEX BY PLS_INTEGER;
   employee_array employee_arraytype;
BEGIN
   SELECT *
     BULK COLLECT INTO employee_array
     FROM employee
    WHERE department = 10;
   --
   FOR i IN employee_array.FIRST .. employee_array.LAST
   LOOP
      -- Do something
   END LOOP;
END;

साहचर्य सरणी किसी भी प्रकार के रिकॉर्ड प्रकार धारण कर सकती है।

आशा है कि यह मदद करता है, Ollie।


17
VALUE_ERRORसंग्रह खाली होने पर पुनरावृति स्थिति उत्पन्न होती है। मैं FOR i IN 1 .. employee_array.COUNTइस मामले में उपयोग करने का सुझाव देना चाहूंगा
unziberla

नीचे दिए गए j-chomel के संस्करण ( stackoverflow.com/a/40579334/1915920 ) sys.odcivarchar2listका यह फायदा है, कि आपके पास हाथ में एक कंस्ट्रक्टर भी है, जैसे फंक्शन परम डिफ़ॉल्ट आरंभीकरण के लिए:sys.odcivarchar2list('val1','val2')
एंड्रियास

11

एक अन्य समाधान एक ओरेकल संग्रह को हैशमैप के रूप में उपयोग करना है:

declare 
-- create a type for your "Array" - it can be of any kind, record might be useful
  type hash_map is table of varchar2(1000) index by varchar2(30);
  my_hmap hash_map ;
-- i will be your iterator: it must be of the index's type
  i varchar2(30);
begin
  my_hmap('a') := 'apple';
  my_hmap('b') := 'box';
  my_hmap('c') := 'crow';
-- then how you use it:

  dbms_output.put_line (my_hmap('c')) ;

-- or to loop on every element - it's a "collection"
  i := my_hmap.FIRST;

  while (i is not null)  loop     
    dbms_output.put_line(my_hmap(i));      
    i := my_hmap.NEXT(i);
  end loop;

end;

11

तुम भी एक का उपयोग कर सकते हैं oracle defined collection

DECLARE 
  arrayvalues sys.odcivarchar2list;
BEGIN
  arrayvalues := sys.odcivarchar2list('Matt','Joanne','Robert');
  FOR x IN ( SELECT m.column_value m_value
               FROM table(arrayvalues) m )
  LOOP
    dbms_output.put_line (x.m_value||' is a good pal');
  END LOOP;
END;

मैं इन-मेमोरी एरे का उपयोग करूंगा। लेकिन .COUNTuziberia द्वारा सुझाए गए सुधार के साथ :

DECLARE
  TYPE t_people IS TABLE OF varchar2(10) INDEX BY PLS_INTEGER;
  arrayvalues t_people;
BEGIN
  SELECT *
   BULK COLLECT INTO arrayvalues
   FROM (select 'Matt' m_value from dual union all
         select 'Joanne'       from dual union all
         select 'Robert'       from dual
    )
  ;
  --
  FOR i IN 1 .. arrayvalues.COUNT
  LOOP
    dbms_output.put_line(arrayvalues(i)||' is my friend');
  END LOOP;
END;

एक अन्य समाधान यह होगा कि यहां @Jchomel जैसे हैशमैप का उपयोग किया जाए ।

ध्यान दें:

Oracle 12c के साथ आप अब सीधे क्वेरी को भी क्वेरी कर सकते हैं !


1

नमूना कार्यक्रम निम्नानुसार और लिंक पर भी उपलब्ध कराया गया है https://oracle-concepts-learning.blogspot.com/

plsql तालिका या संबद्ध सरणी।

        DECLARE 
            TYPE salary IS TABLE OF NUMBER INDEX BY VARCHAR2(20); 
            salary_list salary; 
            name VARCHAR2(20); 
        BEGIN 
           -- adding elements to the table 
           salary_list('Rajnish') := 62000; salary_list('Minakshi') := 75000; 
           salary_list('Martin') := 100000; salary_list('James') := 78000; 
           -- printing the table name := salary_list.FIRST; WHILE name IS NOT null 
            LOOP 
               dbms_output.put_line ('Salary of ' || name || ' is ' || 
               TO_CHAR(salary_list(name))); 
               name := salary_list.NEXT(name); 
            END LOOP; 
        END; 
        /
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.