14开发动态SQL

<!-- /* 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_statement VARCHAR2(100);

BEGIN

sql_statement:='DROP TABLE'||table_name;

EXECUTE IMMEDIATE sql_statement;

END;

 

2.DML

DECLARE

 sql_stat VARCHAR2(100);

BEGIN

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

 EXECUTE IMMEDIATE sql_stat USING &1,&2;

END;

3.RETURNING语句

DECLARE

salary NUMBER(6,2);

sql_stat VARCHAR2(100);

BEGIN

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

||'WHERE empno=:eno RETURNING sal INTO :salary';

EXECUTE IMMEDIATE sql_stat USING &1,&2

RETURNING INTO salary;

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 WHERE deptno=: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 SET sal=sal*(1+:percent/100)'

||'WHERE deptno=:dno'

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

EXECUTE IMMEDIATE sql_stat USING 10,10

 RETURNING BULK COLLECT INTO ename_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;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值