sql >> Database teknologi >  >> RDS >> Oracle

hvordan man erklærer %ROWTYPE af en variabel, der er en svagt skrevet SYS_REFCURSOR?

Det korte svar er, det kan du ikke. Du skal definere en variabel for hver kolonne, der skal returneres.

DECLARE P_RS SYS_REFCURSOR; L_T_COL1 T.COL1%TYPE; L_T_COL1 T.COL2%TYPE; ...

Og hent derefter til listen over kolonner:

FETCH P_RS INTO L_T_COL1, L_T_COL2, ...; 

Dette er smertefuldt, men overskueligt, så længe du ved, hvad du forventer i ref-markøren. Bruger T.* i din procedure gør dette dog skrøbeligt, da tilføjelse af en kolonne til tabellen ville bryde koden, der tror, ​​den ved, hvilke kolonner der er, og hvilken rækkefølge de er i. (Du kan også bryde den mellem miljøer, hvis tabellerne ikke er bygget konsekvent - jeg har set steder, hvor kolonnerækkefølgen er forskellig i forskellige miljøer). Du vil sikkert gerne sikre dig, at du kun vælger de kolonner, du virkelig holder af alligevel, for at undgå at skulle definere variabler for ting, du aldrig vil læse.

Fra 11g kan du bruge DBMS_SQL pakke til at konvertere din sys_refcursor ind i en DBMS_SQL markøren, og du kan udspørge den for at bestemme kolonnerne. Bare som et eksempel på, hvad du kan gøre, vil dette udskrive værdien af ​​hver kolonne i hver række med kolonnenavnet:

DECLARE P_RS SYS_REFCURSOR; L_COLS NUMMER; L_DESC DBMS_SQL.DESC_TAB; L_CURS HELTAL; L_VARCHAR VARCHAR2(4000);BEGIN CAPITALEXTRACT(P_RS => P_RS); L_CURS :=DBMS_SQL.TO_CURSOR_NUMBER(P_RS); DBMS_SQL.DESCRIBE_COLUMNS(C => L_CURS, COL_CNT => L_COLS, DESC_T => L_DESC); FOR i IN 1..L_COLS LOOP DBMS_SQL.DEFINE_COLUMN(L_CURS, i, L_VARCHAR, 4000); ENDSLØKKE; WHILE DBMS_SQL.FETCH_ROWS(L_CURS)> 0 LOOP FOR i IN 1..L_COLS LOOP DBMS_SQL.COLUMN_VALUE(L_CURS, i, L_VARCHAR); DBMS_OUTPUT.PUT_LINE('Række ' || DBMS_SQL.LAST_ROW_COUNT || ':' || l_desc(i).col_name || ' =' || L_VARCHAR); ENDSLØKKE; ENDSLØKKE; DBMS_SQL.CLOSE_CURSOR(L_CURS);END;/

Det er ikke til meget praktisk nytte, og for kortheds skyld behandler jeg hver værdi som en streng, da jeg alligevel bare vil udskrive den. Se på dokumenterne og søg efter eksempler for mere praktiske anvendelser.

Hvis du kun vil have nogle få kolonner fra din ref-markør, kunne du vel gå rundt om l_desc og optag positionen hvor column_name er hvad end du er interesseret i, som en numerisk variabel; du kan så henvise til kolonnen ved den variabel senere, hvor du normalt ville bruge navnet i en markørløkke. Afhænger af, hvad du laver med dataene.

Men medmindre du forventer for ikke at kende kolonnerækkefølgen, du får tilbage, hvilket er usandsynligt, da du ser ud til at kontrollere proceduren - og forudsat at du slipper af med .* s - du er sandsynligvis meget bedre stillet ved at reducere de returnerede kolonner til det minimum, du har brug for, og blot erklære dem alle individuelt.




  1. Hvad er brugen af ​​DECODE-funktionen i SQL?

  2. Sådan overvåger du flere MySQL-forekomster, der kører på samme maskine - ClusterControl-tip og -tricks

  3. Oracle kopiere data til en anden tabel

  4. Tidsbaseret prioritet i Active Record Query