时间:2021-07-21人气:-
1.静态SQLSQL与动态SQL 
Oracle编译PL/SQL程序块分为两个种:其一为前期联编(early binding),即SQL语句在程序编译期间就已经确定,大多数的编译情况属于这种类型;另外一种是后期联编(late binding),即SQL语句只有在运行阶段才能建立,例如当查询条件为用户输入时,那么Oracle的SQL引擎就无法在编译期对该程序语句进行确定,只能在用户输入一定的查询条件后才能提交给SQL引擎进行处理。通常,静态SQL采用前一种编译方式,而动态SQL采用后一种编译方式。 
本文主要就动态SQL的开发进行讨论,并在最后给出一些实际开发的技巧。 
2.动态SQL程序开发 
理解了动态SQL编译的原理,也就掌握了其基本的开发思想。动态SQL既然是一种”不确定”的SQL,那其执行就有其相应的特点。Oracle中提供了Execute immediate语句来执行动态SQL,语法如下: 
复制代码 代码如下:
 
Excute immediate 动态SQL语句 using 绑定参数列表 returning into 输出参数列表;对这一语句作如下说明: 
IDNAMESALARY
100Jacky5600
101Rose3000
102John4500
复制代码 代码如下:
 
create or replace procedure create_table as 
begin 
execute immediate ' 
create table emp(id number, 
name varchar2(10), 
salary number )'; --动态SQL为DDL语句 
insert into emp 
values (100,'jacky',5600); 
insert into emp 
values (101,'rose',3000); 
insert into emp 
values (102,'john',4500); 
end create_table; 
复制代码 代码如下:
 
create or replace procedure find_info(p_id number) as 
v_name varchar2(10); 
v_salary number; 
begin 
execute immediate ' 
select name,salary from emp 
where id=:1' 
using p_id 
returning into v_name,v_salary; --动态SQL为查询语句 
dbms_output.put_line(v_name ||'的收入为:'||to_char(v_salary)); 
exception 
when others then 
dbms_output.put_line('找不到相应数据'); 
end find_info; 
复制代码 代码如下:
 
create or replace procedure find_emp(p_salary number) as 
r_emp emp%rowtype; 
type c_type is ref cursor; 
c1 c_type; 
begin 
open c1 for ' 
select * from emp 
where salary >:1' 
using p_salary; 
loop 
fetch c1 into r_emp; 
exit when c1%notfound; 
dbms_output.put_line('薪水大于‘||to_char(p_salary)||'的员工为:‘); 
dbms_output.put_line('ID为'to_char(r_emp)||' 其姓名为:'||r_emp.name); 
end loop; 
close c1; 
end create_table; 
复制代码 代码如下:
 
declare 
type num_list is varray(20) of number; 
v_id num_list :=num_list(100,101); 
begin 
... 
for i in v_id.first .. v_id.last loop 
... 
execute immediate 'update emp 
set =salary*1.2 
where id=:1 ' 
using v_id(i); 
end loop; 
end; 
复制代码 代码如下: