在PL/SQL程序開發中,可以使用DML語句和事務控制語句,但是還有很多語句(比如DDL語句)不能直接在PL/SQL中執行。這些語句可以使用動態SQL來實現。
PL/SQL塊先編譯然后再執行,動態SQL語句在編譯時不能確定,只有在程序執行時把SQL語句作為字符串的形式由動態SQL命令來執行。在編譯階段SQL語句作為字符串存在,程序不會對字符串中的內容進行編譯,在運行階段再對字符串中的SQL語句進行編譯和執行,動態SQL的語法是:
語法格式:動態SQL
EXECUTE IMMEDIATE 動態語句字符串
[INTO 變量列表]
[USING 參數列表]
語法解析:
如果動態語句是SELECT語句,可以把查詢的結果保存到INTO后面的變量中。如果動態語句中存在參數,USING為語句中的參數傳值。
動態SQL中的參數格式是:[:參數名],參數在運行時需要使用USING傳值。
案例9:動態SQL
代碼演示:動態SQL
DECLARE sql_stmt VARCHAR2(200); --動態SQL語句 emp_id NUMBER(4) := 7566; salary NUMBER(7,2); dept_id NUMBER(2) := 90; dept_name VARCHAR2(14) := 'PERSONNEL'; location VARCHAR2(13) := 'DALLAS'; emp_rec emp%ROWTYPE; BEGIN --無子句的execute immediate EXECUTE IMMEDIATE 'CREATE TABLE bonus1 (id NUMBER, amt NUMBER)'; ① ----using子句的execute immediate sql_stmt := 'INSERT INTO dept VALUES (:1, :2, :3)'; EXECUTE IMMEDIATE sql_stmt USING dept_id, dept_name, location; ② ----into子句的execute immediate sql_stmt := 'SELECT * FROM emp WHERE empno = :id'; EXECUTE IMMEDIATE sql_stmt INTO emp_rec USING emp_id; ③ ----returning into子句的execute immediate sql_stmt := 'UPDATE emp SET sal = 2000 WHERE empno = :1 RETURNING sal INTO :2'; EXECUTE IMMEDIATE sql_stmt USING emp_id RETURNING INTO salary; ④ EXECUTE IMMEDIATE 'DELETE FROM dept WHERE deptno = :num' USING dept_id; ⑤ END;
代碼解析:
① 動態執行一個完整的SQL語句。
② SQL語句中存在3個參數分別標識為:[:1、:2、:3],因此需要用USING關鍵字對三個參數分別賦值。
③ 對動態查詢語句可以使用INTO子句把查詢的結果保存到一個變量中,要求該結果只能是單行。
④ 在Oracle的insert,update,delete語句都可以使用RETURNING子句把操作影響的行中的數據返回,對SQL語句中存在RETURNING子句時,在動態執行時可以使用RETURNING INTO來接收。
⑤ 動態執行參數中可以是:[:數字]也可以是[:字符串]。