|
2012-2-21 答案ADE
A: C未被初始化,因此为NULL, 当作为INDEX BY数组下标时会报VALUE_ERROR异常。
B: C被赋值为空串'', 在用作INDEX BY数组下标时ORACLE会认为它是有效下标,因此不会报错。注意这点与NULL的处理不同。
C: 同上,用的是 '' 做数组下标。
D: 同A, 用NULL做数组下标会报错。
E: 这又是一个陷阱,用SELECT INTO 会使C得到NULL, 而不同于B中用赋值语句得到的空串 '', 所以用作数组下标会报错。
知识点:
请记住 NULL 永远不会相等或不等于NULL (或其他任意东西)。如果你的表达式中有任意一个元素为NULL, 那么绝大多数情况下整个表达式的结果值也为NULL。
假如你需要NULL被另外处理,你必须写特定的逻辑,通常会设计到 NVL 函数(或者它的近亲:NVL2或COALESCE函数)或者用IS NULL/IS NOT NULL操作符。
一个长度为零的字符串(也被称为空串)是一个常量,由两个单引号构成,之间没有任何东西。在绝大多数情况下,ORACLE把长度为零的字符串和NULL值等同处理。
例如,下列代码在执行之后会显示"NULL!":
BEGIN
IF '' IS NULL
THEN
DBMS_OUTPUT.put_line ('NULL!');
END IF;
END;
然而,也存在某些情况,ORACLE会把长度为零的字符串作不同处理。
1.在用字符串作索引的数组(associative array)中,长度为零的字符串会被认为是一个有效的索引值,而NULL则会被拒绝。
2.有些 PL/SQL 的内置函数,当传递给它们的参数中有一个长度为零的字符串,其返回同样会是长度为零的字符串。这些函数包括NVL, COALESCE 和 TO_CHAR。你可以通过执行下列代码来验证这个现象;它不会抛出异常。
DECLARE
TYPE tbl_t IS TABLE OF NUMBER INDEX BY VARCHAR2 (1);
t tbl_t;
BEGIN
t (TO_CHAR ('')) := 1;
t (NVL ('', '')) := 1;
t (COALESCE ('', '')) := 1;
END;
/
3.把一个长度为零的字符串赋值给一个固定宽度的变量时,并不会把NULL值赋给该变量,如下所示:
SQL> declare
2 c char(1);
3 begin
4 c := null;
5 dbms_output.put_line('['||c||']');
6 c := '';
7 dbms_output.put_line('['||c||']');
8 end;
9 /
[]
[ ]
改变空串的处理方法:
在你的当前会话或者系统级执行如下语句,你就可以强迫PL/SQL把空串当作NULL来处理,如同在SQL中一样:
alter session [ or system ] set events '10932 trace name context forever, level 16384';
注意:你使用SET EVENTS时必须非常谨慎,它大部分用于DEBUG的目的,在产品应用中非常罕见(如果有的话)。
下面演示一下这个设置的影响:
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> create or replace procedure plch_proc as
2 type tbl_t is table of number index by varchar2(1);
3 t tbl_t;
4 begin
5 t('') := 1;
6 end;
7 /
Procedure created.
SQL> exec plch_proc
PL/SQL procedure successfully completed.
SQL> alter session set events '10932 trace name context forever, level 16384';
Session altered.
SQL> exec plch_proc
PL/SQL procedure successfully completed.
SQL> alter procedure plch_proc compile;
Procedure altered.
SQL> exec plch_proc
BEGIN plch_proc; END;
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: NULL index table key value
ORA-06512: at "TEST_USER.PLCH_PROC", line 5
ORA-06512: at line 1
鸣谢:这个事件的设置和清除方法由_Nikotin提供。
|
|