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
- NDS โ Native Dynamic SQL
- 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.
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.
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);
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.



