程序如下:
declare
2 type ename_table_type is table of emp.ename%type ;--index by binary_integer;
3 type sal_table_type is table of emp.sal%type; --index by binary_integer;
4 ename_table ename_table_type;
5 sal_table sal_table_type;
6 sql_stat varchar2(200);
7 begin
8 ename_table:=ename_table_type('SCOTT','SMITH','CLERK');
9 sql_stat:='update emp set sal=sal*1.1 where ename=:1 returning into :2';
10 forall i in 1..ename_table.count
11 execute immediate sql_stat using ename_table(i) returning bulk collect into sal_table;
12 for j in 1..ename_table.count loop
13 dbms_output.put_line('雇员:'||ename_table(j)||'的薪水:'||sal_table(j));
14 end loop;
15 end;
问题1:定义表类型时,加index by binary_integer后,在给emp_table赋值时,会出现这个错误:PLS-00222: 在此范围中不存在名为 'ENAME_TABLE_TYPE' 的函数,请问是什么原因?
问题2:第11行处,using ename_table(i)是什么意思?为什么会出现此错误:ORA-00936: 缺失表达式?能说说using的用法吗?
declare
2 type ename_table_type is table of emp.ename%type ;--index by binary_integer;
3 type sal_table_type is table of emp.sal%type; --index by binary_integer;
4 ename_table ename_table_type;
5 sal_table sal_table_type;
6 sql_stat varchar2(200);
7 begin
8 ename_table:=ename_table_type('SCOTT','SMITH','CLERK');
9 sql_stat:='update emp set sal=sal*1.1 where ename=:1 returning into :2';
10 forall i in 1..ename_table.count
11 execute immediate sql_stat using ename_table(i) returning bulk collect into sal_table;
12 for j in 1..ename_table.count loop
13 dbms_output.put_line('雇员:'||ename_table(j)||'的薪水:'||sal_table(j));
14 end loop;
15 end;
问题1:定义表类型时,加index by binary_integer后,在给emp_table赋值时,会出现这个错误:PLS-00222: 在此范围中不存在名为 'ENAME_TABLE_TYPE' 的函数,请问是什么原因?
问题2:第11行处,using ename_table(i)是什么意思?为什么会出现此错误:ORA-00936: 缺失表达式?能说说using的用法吗?
发生这个错误是由于INDEX BY子句构造了一个联合数组,而不是构造一个嵌套表。虽然嵌套表类型的定义显式地定义了一个构造函数,但是联合数组却不需要这种构造函数。
using ename_table(i)相当于实参!在动态SQL拼接中,如果有形参,如你上面的:1和:2这两个形参占位符,用using ename_table(i)就相当于using ename_table(1)去替代:1,用using ename_table(2)去替代:2
这是execute immediate 执行动态SQL的用法
--问题1:
--如果你要那样用,可以这样解决:type ename_table_type is table of emp.ename%type index by binary_integer;
ename_table ename_table_type;type varray_tab is varray(3) of varchar2(10);
var varray_tab :=varray_tab('SCOTT','SMITH','CLERK'); --这样赋值
if ename_table.count <> 0 then
for i in var.first..var.last loop
ename_table(i) := var(i);
end loop;
end if;
....
....--另外,问题2,你动态SQL里returning into :2返回参数是什么啊?既然你用到了占位符:2就需要参数了啊,且,你语法有问题吧,你返回什么啊? 要这样:returning 栏位名称 into :2'
你应该是想这样:
sql_stat:='update emp set sal=sal*1.1 where ename=:1 returning ename,sal';forall i in 1..ename_table.count execute immediate sql_stat using ename_table(i) returning bulk collect into sal_table;
for i in var.first..var.last loop
ename_table(i) := var(i);
end loop;
end if;
哎哟,这个问题才多呢。。脑壳大了
(2)使用联合数组是,个人觉得在以数字作为下标时,不建议使用(使用嵌套表很好).当必须也字符作为下标时.那就不得不用了.
--看这个 你的有多处错误,联合数组跟嵌套表你的概念没弄清以及returning
SQL> edi
已写入 file afiedt.buf 1 declare
2 type ename_table_type is table of emp.empname%type ;--index by binary_integer;
3 type sal_table_type is table of emp.sal%type; --index by binary_integer;
4 ename_table ename_table_type:=ename_table_type('SCOTT','SMITH','CLERK');
5 sal_table sal_table_type:=sal_table_type();
6 sql_stat varchar2(200);
7 begin
8 sql_stat:='update emp set sal=sal*1.1 where empname=:1 returning sal into :2';
9 forall i in 1..ename_table.count
10 execute immediate sql_stat using ename_table(i) returning bulk collect into sal_table;
11 for j in 1..ename_table.count loop
12 dbms_output.put_line('雇员:'||ename_table(j)||'的薪水:'||sal_table(j));
13 end loop;
14* end;
SQL> /
雇员:SCOTT的薪水:5500
雇员:SMITH的薪水:6600
雇员:CLERK的薪水:8800PL/SQL 过程已成功完成。
--你去看这个吧
http://blog.csdn.net/jxst051665/archive/2009/08/10/4430244.aspx
按#8的程序执行、出现了这个错误:ORA-06533: 下标超出数量
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:=sal_table_type();
sql_stat varchar2(200);
begin
ename_table:=ename_table_type('SCOTT','SMITH','CLERK');
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
sal_table.extend;----
dbms_output.put_line('雇员:'||ename_table(j)||'的薪水:'||sal_table(j));
end loop;
end;
--说了嵌套表才显式地定义了一个构造函数,因此初始化的时候用构造函数进行初始化
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:=ename_table_type(); --注意这里在初始化
sal_table sal_table_type:=sal_table_type();
sql_stat varchar2(200);
begin
ename_table:=ename_table_type('SCOTT','SMITH','CLERK');
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
sal_table.extend;----
dbms_output.put_line('雇员:'||ename_table(j)||'的薪水:'||sal_table(j));
end loop;
end;
雇员:SCOTT的薪水:990
雇员:SMITH的薪水:
雇员:CLERK的薪水:
PL/SQL procedure successfully completed
还有一个奇怪的现象:我把emp表的Scott删了,但还能输出Scott的sal
select ename,sal from emp where ename in('SCOTT','SMITH','CLERK') and sal is not null;
ENAME SAL
---------- ---------
SMITH 1089.00
EMP表中没有CLERK、SCOTT的信息
SQL> select ename,sal from emp;
ENAME SAL
---------- ---------
SMITH 1089.00
ALLEN 1870.00
WARD 1485.00
JONES 2975.00
MARTIN 1485.00
BLAKE 3135.00
CLARK 3240.13
KING 6612.50
TURNER 1760.00
ADAMS 1200.00
JAMES 1155.00
FORD 3000.00
MILLER 1851.50
13 rows selected
这么给你详细解释下原因吧:
假设情况:
(1)。ename in('SCOTT','SMITH','ALLEN') EMP表中这三个员工都有记录,且工资SAL不为空,
这种情况下嵌套表ename_table(i)和sal_table(j)才一一对应上,即上面的代码不会报错!
(2)。如果其中一个员工不存在,如你所说为什么吧SCOTT删除了,执行结果还有SCOTT!其实这个是SCOTT工资是SMITH对应的工资
这点就是你问的下表超出数量的错误。
详细点来说:你首先构造的嵌套表 ename_table为三个,即 ('SCOTT','SMITH','ALLEN'),程序是根据姓名来更新对应工资,返回更新后的工资。
但是此时你emp表没有SCOTT对应的记录,因此返回结果就只有两个,即('SMITH','ALLEN')的工资,这时sal_table只有两个值,
接下来,你想打印出三个员工更新后的工资,循环三次,而 嵌套表sal_table只有两个,因此报下表超出数量的错误!(这点明白了吧?)
再来说说为什么你删除了SCOTT,结果还有SCOTT的工资:前面已经说清楚了,你ename_table打印出的是三个员工,但是sal_table只有两个('SMITH','ALLEN')的工资,
此时两个嵌套表的维数不同,并不是跟以前员工和对应工资是一一对应的,此时SCOTT对应的是sal_table(1),即对应的是SMITH的工资 。 说到这个份上,楼主应该理解了吧!
SMITH 800
ALLEN 1600
SCOTT NULL执行后: PL/SQL block, executed in 0 sec.
雇员:SCOTT的薪水:
雇员:SMITH的薪水:880
雇员:ALLEN的薪水:1760
Total execution time 0.015 sec.