The 10 October 2011 quiz tested your knowledge of the effect of a NULL value being passed to the EXISTS method. Iudith Mentzel did some further analysis and offers up these insights:
First, as probably expected, we cannot use NULL as an array index value, neither for an associative array indexed by PLS_INTEGER nor for one indexed by a VARCHAR2, they both raise VALUE_ERROR:
DECLARE
my_list DBMS_SQL.number_table;
BEGIN
my_list(NULL) := 100;
IF my_list.EXISTS(NULL) THEN
DBMS_OUTPUT.PUT_LINE('NULL index exists !');
ELSE
DBMS_OUTPUT.PUT_LINE('NULL index does not exist !');
END IF;
END;
/
DECLARE
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: NULL index table key value
ORA-06512: at line 4
DECLARE
TYPE array_t IS TABLE OF NUMBER INDEX BY VARCHAR2(5);
my_list array_t;
BEGIN
my_list(NULL) := 100;
IF my_list.EXISTS(NULL) THEN
DBMS_OUTPUT.PUT_LINE('NULL index exists !');
ELSE
DBMS_OUTPUT.PUT_LINE('NULL index does not exist !');
END IF;
END;
/
DECLARE
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: NULL index table key value
ORA-06512: at line 5
However, for a VARCHAR2 index we can use an empty string ( '' ) as an index without error, and it is NOT the same as a NULL index:
DECLARE
TYPE array_t IS TABLE OF NUMBER INDEX BY VARCHAR2(5);
my_list array_t;
BEGIN
my_list('') := 100;
IF my_list.EXISTS(NULL) THEN
DBMS_OUTPUT.PUT_LINE('NULL index exists !');
ELSE
DBMS_OUTPUT.PUT_LINE('NULL index does not exist !');
END IF;
IF my_list.EXISTS('') THEN
DBMS_OUTPUT.PUT_LINE(' '''' index exists !');
ELSE
DBMS_OUTPUT.PUT_LINE(' '''' index does not exist !');
END IF;
END;
/
NULL index does not exist !
'' index exists !
This is in spite of the fact that a VARCHAR2 variable having an empty string assigned to it is considered as NULL (which, as we know, is NOT the case for a CHAR variable):
DECLARE
my_var VARCHAR2(5) := '' ;
BEGIN
IF my_var IS NULL THEN
DBMS_OUTPUT.PUT_LINE('my_var IS NULL');
ELSE
DBMS_OUTPUT.PUT_LINE('my_var IS NOT NULL');
END IF;
END;
/
my_var IS NULL
Strange NULL oddities ...
Without this quiz, no one has probably ever thought of trying to use a NULL or a NULL variable as an array index, just to see what happens ...it is entirely the merit of PL/SQL Challenge to make us dig that deeply :-)
And you can further extend the example: even if you assing the empty string to an variable you can use that variable as an index to the collection:
ReplyDeleteDECLARE
TYPE array_t IS TABLE OF NUMBER INDEX BY VARCHAR2(5);
my_list array_t;
my_index VARCHAR2(5) := '';
BEGIN
IF my_index IS NULL THEN
DBMS_OUTPUT.PUT_LINE('my_index IS NULL');
ELSE
DBMS_OUTPUT.PUT_LINE('my_index IS NOT NULL');
END IF;
my_list(my_index) := 100;
IF my_list.EXISTS(NULL) THEN
DBMS_OUTPUT.PUT_LINE('NULL index exists !');
ELSE
DBMS_OUTPUT.PUT_LINE('NULL index does not exist !');
END IF;
IF my_list.EXISTS( my_index) THEN
DBMS_OUTPUT.PUT_LINE('index "my_index" with '
|| (CASE WHEN (my_index IS NULL)
THEN 'NULL-value'
ELSE 'value "' || my_index || '"' END)
|| ' exists !');
ELSE
DBMS_OUTPUT.PUT_LINE('index "my_index" with '
|| (CASE WHEN (my_index IS NULL)
THEN 'NULL-value'
ELSE 'value "' || my_index || '"' END)
|| ' does not exists !');
END IF;
END;
/