Sök…


Syntax

  • Markörens markörnamn Är ditt_select_statement
  • Markörens markörnamn (param TYPE) Är din_select_statement_using_param
  • FÖR x in ( din_select_statement ) LOOP ...

Anmärkningar

Förklarade markörer är svåra att använda, och du bör föredra FOR loopar i de flesta fall. Vad som är mycket intressant i markörer jämfört med enkla FOR slingor är att du kan parametrera dem.

Det är bättre att undvika att göra slingor med PL / SQL och markörer istället för att använda Oracle SQL ändå. Men för människor som är vana vid procedurspråk kan det vara mycket lättare att förstå.

Om du vill kontrollera om en post finns och sedan göra olika saker beroende på om posten finns eller inte, är det vettigt att använda MERGE uttalanden i rena ORACLE SQL-frågor istället för att använda markörslingor. (Observera att MERGE endast finns i Oracle-utgåvor> = 9i).

Parameteriserad "FOR loop" markör

DECLARE
  CURSOR c_emp_to_be_raised(p_sal emp.sal%TYPE) IS 
    SELECT * FROM emp WHERE  sal < p_sal;
BEGIN
  FOR cRowEmp IN c_emp_to_be_raised(1000) LOOP
    dbms_Output.Put_Line(cRowEmp .eName ||' ' ||cRowEmp.sal||'... should be raised ;)');
  END LOOP;
END;
/

Implicit "FOR loop" -markör

BEGIN
  FOR x IN (SELECT * FROM emp WHERE sal < 100) LOOP
    dbms_Output.Put_Line(x.eName ||' '||x.sal||'... should REALLY be raised :D');
  END LOOP;
END;
/
  • Den första fördelen är att det inte finns någon långtråkig deklaration att göra (tänk på den hemska "CURSOR" -saken du hade i tidigare versioner)
  • den andra fördelen är att du först bygger din utvalda fråga, sedan när du har vad du vill kan du omedelbart få åtkomst till fälten för din fråga ( x.<myfield> ) i din PL / SQL-slinga
  • Loopen öppnar markören och hämtar en post åt gången för varje slinga. I slutet av slingan är markören stängd.
  • Implicita markörer är snabbare eftersom tolkens arbete växer när koden blir längre. Ju mindre kod, desto mindre arbete har tolken att göra.

Arbetar med SYS_REFCURSOR

SYS_REFCURSOR kan användas som SYS_REFCURSOR när du enkelt behöver hantera en lista som returneras inte från en tabell, men mer specifikt från en funktion:

funktion som returnerar en markör

CREATE OR REPLACE FUNCTION list_of (required_type_in IN VARCHAR2)
   RETURN SYS_REFCURSOR
IS
   v_ SYS_REFCURSOR;
BEGIN
   CASE required_type_in
      WHEN 'CATS'
      THEN
         OPEN v_ FOR
           SELECT nickname FROM (
                select 'minou' nickname from dual
      union all select 'minâ'           from dual
      union all select 'minon'          from dual         
           );
      WHEN 'DOGS'
      THEN
         OPEN v_ FOR
              SELECT dog_call FROM (
                select 'bill'   dog_call from dual
      union all select 'nestor'          from dual
      union all select 'raoul'           from dual         
           );
   END CASE;
   -- Whit this use, you must not close the cursor.
   RETURN v_;
END list_of;
/

och hur man använder det:

DECLARE
   v_names   SYS_REFCURSOR;
   v_        VARCHAR2 (32767);
BEGIN
   v_names := list_of('CATS');
   LOOP
      FETCH v_names INTO v_;
      EXIT WHEN v_names%NOTFOUND;
      DBMS_OUTPUT.put_line(v_);
   END LOOP;
   -- here you close it
   CLOSE v_names;
END;
/

Hantering av en CURSOR

  • Förklara markören för att skanna en lista med poster
  • Öppna den
  • Hämta aktuell post i variabler (denna stegvisa position)
  • Använd %notfound att upptäcka slutlistan
  • Glöm inte att stänga markören för att begränsa resursförbrukningen i nuvarande sammanhang

-

DECLARE
  CURSOR curCols IS -- select column name and type from a given table
         SELECT column_name, data_type FROM all_tab_columns where table_name='MY_TABLE';
  v_tab_column all_tab_columns.column_name%TYPE;
  v_data_type all_tab_columns.data_type%TYPE;
  v_ INTEGER := 1;
BEGIN
  OPEN curCols;
  LOOP
     FETCH curCols INTO v_tab_column, v_data_type;
     IF curCols%notfound OR v_ > 2000 THEN
       EXIT;
     END IF;
     dbms_output.put_line(v_||':Column '||v_tab_column||' is of '|| v_data_type||' Type.');
     v_:= v_ + 1;
  END LOOP;

  -- Close in any case
  IF curCols%ISOPEN THEN  
     CLOSE curCols;
  END IF;
END;
/


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow