天猫网站建设分析公司网站推广
动态SQL对于我有一种不应忘怀的记忆,这几篇关于动态SQL的博客,算是给无缘一面的一位朋友的承诺,也是给自己一个交代。
前路漫漫,无心睡眠,我以为只有我睡不着,原来你也睡不着,加油,哈哈!
--17.5 动态SQL的性能优化技巧
--17.5.1 用绑定变量改善性能--使用字符串拼接的方法来执行UPDATE语句,执行速度慢
DECLAREv_sal NUMBER:=3000; --保存调薪后的薪资v_empno NUMBER:=7369;v_sql VARCHAR2(500); --保存动态SQL语句的字符串
BEGINv_sql:='UPDATE emp SET sal='||v_sal||'WHERE empno='||v_empno;EXECUTE IMMEDIATE v_sql;
END; --使用绑定变量来执行UPDATE语句,具有显著的性能和安全性优势
DECLAREv_sal NUMBER:=3000; --保存调薪后的薪资v_empno NUMBER:=&empno;v_sql VARCHAR2(500); --保存动态SQL语句的字符串
BEGINv_sql:='UPDATE emp SET sal=:1 WHERE empno=:2';EXECUTE IMMEDIATE v_sql USING v_sal,v_empno;
END; --17.5.2 重复的绑定占位符
--执行动态SQL语句,为重复的val_in传入多次作为绑定变量
DECLAREcol_in VARCHAR2(10):='sal'; --列名start_in DATE; --起始日期end_in DATE; --结束日期val_in NUMBER; --输入参数值dml_str VARCHAR2 (32767):= 'UPDATE emp SET '|| col_in|| ' = :valWHERE hiredate BETWEEN :lodate AND :hidateAND :val IS NOT NULL'; --动态SQL语句
BEGINEXECUTE IMMEDIATE dml_strUSING val_in, start_in, end_in, val_in;
END;select * from emp_history order by update_date desc;--代码17.18 执行PL/SQL动态语句时的重复绑定占位符的处理
DECLAREcol_in VARCHAR2(10):='sal'; --列名start_in DATE; --起始日期end_in DATE; --结束日期val_in NUMBER; --输入参数值dml_str VARCHAR2 (32767):= 'BEGINUPDATE emp SET '|| col_in|| ' = :valWHERE hiredate BETWEEN :lodate AND :hidateAND :val IS NOT NULL;END;'; --动态PL/SQL语句
BEGIN--执行动态SQL语句,占位符:val只需要指定一次val_in即可EXECUTE IMMEDIATE dml_strUSING val_in, start_in, end_in;
END;--17.5.3 传递NULL参数
--错误的写法
BEGINEXECUTE IMMEDIATE 'UPDATE emp SET comm=:x'USING NULL;
END;--正确的写法
DECLAREnull_comm NUMBER; --定义一个未初始化的变量
BEGINEXECUTE IMMEDIATE 'UPDATE emp SET comm=:x'USING null_comm; --将该变量作为绑定变量的值传入
END;--17.5.4 动态SQL异常处理
--代码17.19 在执行动态SQL时使用异常处理机制
CREATE OR REPLACE PROCEDURE ddl_execution (ddl_string IN VARCHAR2)AUTHID CURRENT_USER IS --使用调用者权限
BEGINEXECUTE IMMEDIATE ddl_string; --执行动态SQL语句
EXCEPTIONWHEN OTHERS --捕捉错误 THENDBMS_OUTPUT.PUT_LINE ( --显示错误消息'动态SQL语句错误:' || DBMS_UTILITY.FORMAT_ERROR_STACK);DBMS_OUTPUT.PUT_LINE ( --显示当前执行的SQL语句' 执行的SQL语句为: "' || ddl_string || '"');RAISE;
END ddl_execution;BEGIN
ddl_execution ('select pd from t_pd');
END;