14开发动态SQL

来源:互联网 发布:程序员接单知乎 编辑:程序博客网 时间:2024/04/30 10:05

<!-- /* Font Definitions */ @font-face{font-family:宋体;panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-alt:SimSun;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:3 135135232 16 0 262145 0;}@font-face{font-family:"/@宋体";panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal{mso-style-parent:"";margin:0cm;margin-bottom:.0001pt;text-align:justify;text-justify:inter-ideograph;mso-pagination:none;font-size:10.5pt;mso-bidi-font-size:12.0pt;font-family:"Times New Roman";mso-fareast-font-family:宋体;mso-font-kerning:1.0pt;} /* Page Definitions */ @page{mso-page-border-surround-header:no;mso-page-border-surround-footer:no;}@page Section1{size:595.3pt 841.9pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;mso-header-margin:42.55pt;mso-footer-margin:49.6pt;mso-paper-source:0;layout-grid:15.6pt;}div.Section1{page:Section1;} /* List Definitions */ @list l0{mso-list-id:1847088892;mso-list-type:hybrid;mso-list-template-ids:634394156 -1700990714 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}@list l0:level1{mso-level-tab-stop:18.0pt;mso-level-number-position:left;margin-left:18.0pt;text-indent:-18.0pt;}ol{margin-bottom:0cm;}ul{margin-bottom:0cm;}-->

一:区别

静态SQL:在PL/SQL中直接嵌入的SQL语句。静态SQL性能优于动态SQL

动态SQl:在运行PL/SQL时动态输入的SQL语句。

二:动态SQL处理方法

1.      EXECUTE IMMEDIATE语句

可以处理:DDLDMLDCL以及单行SELECT语句。注:不能用于处理多行查询语句

2.      OPEN-FORFETCHCLOSE语句

使用OPEN-FOR语句打开游标,使用FETCH语句循环提取数据。

3.      使用批量动态SQL

 

使用EXECUTE IMMEDIATE语句

1.DCL

CREATE OR REPLACE PROCEDURE drop_table(table_name VARCHAR2)

IS

sql_statementVARCHAR2(100);

BEGIN

sql_statement:='DROPTABLE'||table_name;

EXECUTE IMMEDIATEsql_statement;

END;

 

2.DML

DECLARE

 sql_stat VARCHAR2(100);

BEGIN

 sql_stat := 'UPDATE emp SETsal=sal*(1+:percent/100)'||'WHERE deptno=:dno';

 EXECUTE IMMEDIATE sql_stat USING&1,&2;

END;

3.RETURNING语句

DECLARE

salaryNUMBER(6,2);

sql_statVARCHAR2(100);

BEGIN

sql_stat:='UPDATEemp SET sal=sal*(1+:percent/100)'

||'WHEREempno=:eno RETURNING sal INTO :salary';

EXECUTE IMMEDIATEsql_stat USING &1,&2

RETURNING INTOsalary;

dbms_output.put_line('新工资:'||salary);

END;

 

4.用游标的动态SQL

DECLARE

TYPE empcurtyp IS REF CURSOR;

emp_cv empcurtyp;

emp_record emp%ROWTYPE;

sql_stat VARCHAR2(100);

BEGIN

 sql_stat:='SELECT * FROM emp WHEREdeptno=:dno';

 OPEN emp_cv FOR sql_stat USING&dno;

 LOOP

  FETCH emp_cv INTO emp_record;

  EXIT WHEN emp_cv%NOTFOUND;

  dbms_output.put_line('雇员名:'||emp_record.ename||',工资:'||emp_record.sal);

END LOOP;

CLOSE emp_cv;

END;

 

5.BULK COLLECT INTO

DECLARE

TYPE ename_table_type IS TABLE OF emp.ename%TYPE

 INDEX BY BINARY_INTEGER;

TYPE sal_table_type IS TABLE OF emp.sal%TYPE

 INDEX BY BINARY_INTEGER;

ename_table ename_table_type;

sal_table sal_table_type;

sql_stat VARCHAR2(100);

BEGIN

 sql_stat:='UPDATE emp SETsal=sal*(1+:percent/100)'

||'WHERE deptno=:dno'

||'RETURNING ename,sal INTO :name,:salary';

EXECUTE IMMEDIATE sql_stat USING 10,10

 RETURNING BULK COLLECT INTOename_table,sal_table;

FOR i IN 1..ename_table.COUNT LOOP

 dbms_output.put_line('雇员'||ename_table(i)||'的新工资为'||sal_table(i));

END LOOP;

END;

 

6.FETCH语句中使用BULK子句。

DECLARE

 TYPE empcurtyp IS REF CURSOR;

 emp_cv empcurtyp;

TYPE ename_table_type IS TABLE OF emp.ename%TYPE

 INDEX BY BINARY_INTEGER;

ename_table ename_table_type;

sql_stat VARCHAR2(100);

BEGIN

sql_stat:='SELECT ename FROM emp WHERE job:=title';

OPEN emp_cv FOR sql_stat USING '&job';

FETCH emp_cv BULK COLLECT INTO ename_table;

FOR i IN 1..ename_table.COUNT LOOP

 dbms_output.put_line(ename_table(i));

END LOOP;

CLOSE emp_cv;

END;

7.FORALL语句中使用BULK子句:可以为输入变量提供多个输入值。但只适用于DELETEUPDATEDELETE语句。

DECLARE

TYPE ename_table_type IS TABLE OF emp.ename%TYPE;

TYPE sal_table_type IS TABLE OF emp.sal%TYPE;

ename_table ename_table_type;

sal_table sal_table_type;

sql_stat VARCHAR2(100);

BEGIN

ename_table:=ename_table_type('SCOTT','SMITH','CLARK');

sql_stat:='UPDATE emp SET sal=sal*1.1 WHERE ename=:1'

||'RETURNING sal INTO :2';

FORALL i IN 1..ename_table.COUNT

EXECUTE IMMEDIATE sql_stat USING ename_table(i)

RETURNING BULK COLLECT INTO sal_table;

FOR j IN 1..ename_table.COUNT LOOP

dbms_output.put_line('雇员'||ename_table(j)||'的新工资为'||sal_table(j));

END LOOP;

END;

习题:

编写PL/SQL在动态SQL中使用BULK子句根据输入的多个订单号,更新交付日期当前日期,并返回每个订单对应的客户号。

DECLARE

  2  sql_stat VARCHAR2(100);

  3  TYPE ordid_table_type IS TABLE OF ord.ord_id%TYPE;

  4  ordid_table ordid_table_type;

  5  TYPE cid_table_type IS TABLE OF ord.customer_id%TYPE;

  6  cid_table cid_table_type;

  7 BEGIN

  8  sql_stat:='UPDATE ord SET ship_date=SYSDATE'||

  9 'WHERE ord_id=:b'||

 10 'RETURNING customer_id INTO :c';

 11 ordid_table:=ordid_table_type(&1,&2,&3);

 12 FORALL i IN 1..ordid_table.COUNT

 13  EXECUTE IMMEDIATE sql_stat USING ordid_table(i)

 14  RETURNING BULK COLLECT INTO cid_table;

 15  FOR i IN 1..cid_table.COUNT LOOP

 16  dbms_output.put_line('订单:'||ordid_table(i)||',客户:'||cid_table(i));

 17  END LOOP;

 18  END;

原创粉丝点击