EXECUTE IMMEDIATE语句处理SELECT和DML语句的区别
1.如果使用动态的SELECT语句且只返回一行,可以使用EXECUTE
IMMEDIATE INTO USING语法:
09:42:42 SCOTT@ orcl>declare 09:42:43 2 v_empid scott.EMP.EMPLOYEE_ID%TYPE :=100; 09:42:43 3 v_name varchar2(20); 09:42:43 4 v_sql varchar2(500); 09:42:43 5 begin 09:42:43 6 v_sql := 'select t.FIRST_NAME ||'' ''|| t.LAST_NAME name from scott.emp t where t.EMPLOYEE_ID =:v_id'; 09:42:43 7 EXECUTE IMMEDIATE v_sql into v_name using v_empid ; 09:42:43 8 DBMS_OUTPUT.PUT_LINE(v_name); 09:42:43 9 end; 09:42:43 10 / Steven King
2.如果动态的DML语句且返回一行,上述的语句就不适用了,例如:
09:57:36 SCOTT@ orcl> declare 09:57:38 2 v_empid scott.EMP.EMPLOYEE_ID%TYPE :=100; 09:57:38 3 v_email varchar2(100):='tom@test.com'; 09:57:38 4 v_sql varchar2(500); 09:57:38 5 v_name varchar2(200); 09:57:38 6 begin 09:57:38 7 v_sql := 'update emp t set t.EMAIL=:v_email where t.EMPLOYEE_ID=:v_id returning t.FIRST_NAME || t.last_name into :v_name'; 09:57:38 8 EXECUTE IMMEDIATE v_sql into v_name using v_email,v_empid ; 09:57:38 9 dbms_output.put_line(v_name); 09:57:38 10 end; 09:57:40 11 / declare * ERROR at line 1: ORA-01008: not all variables bound ORA-06512: at line 8
oracle报错说有变量为做绑定,其实我的所有变量都已绑定,在动态SQL中我的条件在前是两个变量(v_email,v_id),返回值在后一个变量(t.FIRST_NAME || t.last_name),但在真正做绑定变量时,却是返回值在前,变量在后。Oracle是按顺序去绑定的,所以在绑定变量时变量和返回值要对应上。
declare v_empid scott.EMP.EMPLOYEE_ID%TYPE :=100; v_email varchar2(100):='tom@test.com'; v_sql varchar2(500); v_name varchar2(200); begin v_sql := 'update emp t set t.EMAIL=:v_email where t.EMPLOYEE_ID=:v_id returning t.FIRST_NAME || t.last_name into :v_name'; EXECUTE IMMEDIATE v_sql using v_email,v_empid return into v_name ; dbms_output.put_line(v_name); end;
后记:SELECT和DML在使用动态语句中还有一个区别就是在DML返回值必须加上return或returning,而SELECT是没有的。