靜態SQL是前置編譯綁定,動態SQL是后期執行時才編譯綁定。
場景:
動態SQL適用於表名及查詢字段名未知的情況。在已知查詢字段名及表名的情況下,使用動態SQL(字符串拼接方式)會增加硬解析的開銷,在這種情況下,建議使用靜態SQL,這樣可以提高執行效率。在過程過程用拼湊的動態sql效率並不高。
因此,真實業務下適用動態sql的場景非常少,使用時也必須注意表結構的變動等因素,應該盡量在業務開發中使用動態sql。本人一般使用動態sql做數據采集;
用execute immediate實現動態sql:
----ddl begin execute immediate 'create table l_test(name varchar2(8))'; end;
帶參數:
declare ----帶參數 v_name l_test.name%type; v_insql varchar(100); begin v_name := '張三'; v_insql := 'insert into l_test(name)values(:1)'; execute immediate v_insql using v_name; commit; end;

返回一行記錄:
declare ----帶參數 v_name l_test.name%type; v_sql varchar(100); v_rec l_test%rowtype; begin v_name := '張三'; v_sql := 'select * from l_test t where t.name=:v_n'; execute immediate v_sql into v_rec using v_name; dbms_output.put_line(v_rec.name); end;
返回多行記錄:
declare --v_name l_test.name%type; v_sql varchar(100); type t_rec IS TABLE OF l_test%ROWTYPE; v_arry_test t_rec; begin v_name := '張三'; v_sql := 'select * from l_test t'; execute immediate v_sql bulk collect into v_arry_test; for i in 1 .. v_arry_test.count loop dbms_output.put_line(v_arry_test(i).name); end loop; end;

結合游標:
declare v_name l_test.name%type; v_sql varchar(100); type cur_type is ref cursor; v_cur cur_type; type t_rec IS TABLE OF l_test%ROWTYPE; v_arry_test t_rec; begin v_name := '張三'; v_sql := 'select * from l_test t where name=:v_n'; open v_cur for '' || v_sql using v_name; fetch v_cur bulk collect into v_arry_test; close v_cur; for i in 1 .. v_arry_test.count loop dbms_output.put_line(v_arry_test(i).name); end loop; end;
