Oracle PL/SQL Dynamic SQL Tutorial: Execute Immediate & DBMS_SQL

Vad รคr dynamisk SQL?

Dynamisk SQL รคr en programmeringsmetod fรถr att generera och kรถra satser under kรถrning. Det anvรคnds frรคmst fรถr att skriva de allmรคnna och flexibla programmen dรคr SQL-satserna kommer att skapas och exekveras under kรถrning baserat pรฅ kravet.

Sรคtt att skriva dynamisk SQL

PL/SQL ger tvรฅ sรคtt att skriva dynamisk SQL

  1. NDS โ€“ Native Dynamic SQL
  2. DBMS_SQL

NDS (Native Dynamic SQL) โ€“ Kรถr omedelbart

Native Dynamic SQL รคr det enklare sรคttet att skriva dynamisk SQL. Den anvรคnder kommandot 'EXECUTE IMMEDIATE' fรถr att skapa och kรถra SQL under kรถrning. Men fรถr att anvรคnda det hรคr sรคttet mรฅste datatypen och antalet variabler som ska anvรคndas vid en kรถrning vara kรคnda tidigare. Det ger ocksรฅ bรคttre prestanda och mindre komplexitet jรคmfรถrt med DBMS_SQL.

syntax

EXECUTE IMMEDIATE(<SQL>)
[INTO<variable>]
[USING <bind_variable_value>]
  • Ovanstรฅende syntax visar kommandot EXECUTE IMMEDIATE.
  • Klausul INTO รคr valfri och anvรคnds endast om den dynamiska SQL-koden innehรฅller en select-sats som hรคmtar vรคrden. Variabeltypen ska matcha variabeltypen fรถr select-satsen.
  • Klausul USING รคr valfri och anvรคnds endast om den dynamiska SQL-koden innehรฅller nรฅgon bindningsvariabel.

Exempelvis 1: I det hรคr exemplet kommer vi att hรคmta data frรฅn emp-tabellen fรถr emp_no '1001' med hjรคlp av NDS-satsen.

NDS - Utfรถr omedelbart

DECLARE
lv_sql VARCHAR2(500);
lv_emp_name VARCHAR2(50):
ln_emp_no NUMBER;
ln_salary NUMBER;
ln_manager NUMBER;
BEGIN
ly_sql:=;SELECT emp_name,emp_no,salary,manager FROM emp WHERE
emp_no=:empmo:;
EXECUTE IMMEDIATE lv_sql INTO lv_emp_name,ln_emp_no:ln_salary,ln_manager
USING 1001;
Dbms_output.put_line('Employee Name:โ€˜||lv_emp_name);
Dbms_output.put_line('Employee Number:โ€˜||ln_emp_no);
Dbms_output.put_line(โ€˜Salary:'||ln_salaiy);
Dbms_output.put_line('Manager ID:โ€˜||ln_manager);
END;
/

Produktion

Employee Name : XXX 
Employee Number: 1001 
Salary: 15000 
Manager ED: 1000

Kodfรถrklaring:

  • Kodrad 2-6: Deklarerar variabler.
  • Kodrad 8: Ramar in SQL vid kรถrning. SQL innehรฅller bindningsvariabeln i where-villkoret ':empno'.
  • Kodrad 9: Exekvera den inramade SQL-texten (vilket gรถrs i kodrad 8) med NDS-kommandot 'EXECUTE IMMEDIATE'
  • Variablerna i 'INTO'-satsen (lv_emp_name, ln_emp_no, ln_salary, ln_manager) anvรคnds fรถr att hรฅlla de hรคmtade vรคrdena frรฅn SQL-frรฅgan (emp_name, emp_no, salary, manager)
  • 'USING'-satsen ger vรคrdena till bindningsvariabeln i SQL-frรฅgan (:emp_no).
  • Kodrad 10-13: Visar de hรคmtade vรคrdena.

DBMS_SQL fรถr dynamisk SQL

PL/SQL tillhandahรฅller DBMS_SQL-paketet som lรฅter dig arbeta med dynamisk SQL. Processen att skapa och exekvera den dynamiska SQL-koden innehรฅller fรถljande process.

  • ร–PPNA MARKรถren: Dynamisk SQL kommer att kรถras pรฅ samma sรคtt som en markรถren. Sรฅ fรถr att kunna kรถra SQL-satsen mรฅste vi รถppna markรถren.
  • PARSE SQL: Nรคsta steg รคr att analysera dynamisk SQL. Denna process kommer bara att kontrollera syntaxen och hรฅlla frรฅgan redo att kรถras.
  • BIND VARIABEL Vรคrden: Nรคsta steg รคr att tilldela vรคrdena fรถr bindningsvariabler om nรฅgra.
  • DEFINIERA KOLUMN: Nรคsta steg รคr att definiera kolumnen med hjรคlp av deras relativa positioner i select-satsen.
  • Utfรถrande: Nรคsta steg รคr att kรถra den analyserade frรฅgan.
  • Hร„MTA Vร„RDEN: Nรคsta steg รคr att hรคmta de exekverade vรคrdena.
  • STร„NG MARKร–R: Nรคr resultaten har hรคmtats ska markรถren stรคngas.

Exempelvis 1: I det hรคr exemplet kommer vi att hรคmta data frรฅn emp-tabellen fรถr emp_no '1001' med hjรคlp av DBMS_SQL-satsen.

DBMS_SQL fรถr dynamisk SQL

DECLARE
lv_sql VARCHAR2(500);
lv_emp_name VARCHAR2(50);
ln_emp_no NUMBER;
ln_salary NUMBER;
ln_manager NUMBER;
ln_cursor_id NUMBER;
ln_rows_processed;
BEGIN
lv_sql:=โ€˜SELECT emp_name,emp_no,salary,manager FROM emp WHERE
emp_no=:empmoโ€™;
in_cursor_id:=DBMS_SQL.OPEN_CURSOR;

DBMS_SQL.PARSE(ln_cursor_id,lv_sql,DBMS_SQL.NATIVE);

DBMS_SQL.BIXD_VARLABLE(ln_cursor_id,:โ€˜empnoโ€˜,1001);

DBMS_SQL.DEFINE_COLUMN(ln_cursor_ici,1,ln_emp_name);
DBMS_SQL.DEFINE_COLUMN(ln_cursor_id,2,ln_emp_no);
DBMS_SQL .DEFINE_COLUMN(ln_cursor_id,3,ln_salary);
DBMS_SQL .DEFINE_COLUMN(ln_cursor_id,4,ln_manager);

ln_rows__processed:=DBMS_SQL.EXECUTE(ln_cursor_id);

DBMS_SQL fรถr dynamisk SQL

LOOP
IF DBMS_SQL.FETCH_ROWS(ln_cursor_id)=0
THEN
EXIT;
ELSE
DBMS_SQL.COLUMN_VALUE(ln_cursor_id,1,lv_emp_name); 
DBMS_SQL.COLUMN_VALUE(ln_cursor_id,2,ln_emp_no);
DBMS_SQL.COLUMN_VALUE(ln_cursor_id,3,In_salary);
DBMS_SQL.COLUMN_VALUE(ln_cursor_id,4,In_manager);
Dbms_output.put_line('Employee Name:โ€˜||lv_emp_name); 
Dbms_output.put_line('Employee Number:lโ€˜||ln_emp_no); 
Dbms_output.put_line(โ€˜Salary:โ€˜||ln_salary); 
Dbms_output.put_line('Manager ID :โ€˜| ln_manager);
END IF;
END LOOP;

DBMS_SQL.CLOSE_ClIRSOR(ln_cursor_id);

END:
/

Produktion

Employee Name:XXX 
Employee Number:1001 
Salary:15000 
Manager ID:1000

Kodfรถrklaring:

  • Kodrad 1-9: Variabel deklaration.
  • Kodrad 10: Ramar in SQL-satsen.
  • Kodrad 11: ร–ppna markรถren med DBMS_SQL.OPEN_CURSOR. Det kommer att returnera markรถr-id som รถppnas.
  • Kodrad 12: Efter att markรถren har รถppnats analyseras SQL.
  • Kodrad 13: Bindvariabel '1001' tilldelar markรถr-id istรคllet ':empno'.
  • Kodrad 14-17: Definiera kolumnnamnet baserat pรฅ deras relativa position i SQL-satsen. I vรฅrt fall รคr den relativa positionen (1) emp_name, (2) emp_no (3) lรถn (4) chef. Sรฅ baserat pรฅ denna position definierar vi mรฅlvariabeln.
  • Kodrad 18: Kรถr frรฅgan med DBMS_SQL.EXECUTE. Det returnerar antalet bearbetade poster.
  • Kodrad 19-33: Hรคmta posterna med en loop och visa densamma.
  • Kodrad 20: DBMS_SQL.FETCH_ROWS kommer att hรคmta en post frรฅn de rader som behandlas. Den kan anropas upprepade gรฅnger fรถr att hรคmta alla rader. Om den inte kan hรคmta rader kommer den att returnera 0, och dรคrmed lรคmna slingan.

Sammanfattning

I det hรคr avsnittet har vi diskuterat dynamisk SQL och sรคtten att exekvera DYNAMISK SQL. Vi har ocksรฅ sett de olika stegen i exekvering av dynamisk SQL pรฅ bรฅda sรคtten. Vi har ocksรฅ sett exemplen dรคr samma scenario hanteras pรฅ bรฅde NDS- och DBMS_SQL-sรคtt fรถr att utfรถra exekvering vid kรถrning.

Sammanfatta detta inlรคgg med: