Проблемът е, че dbms_utility.comma_to_table
процедура
изисква елементите на списъка да бъдат валидни идентификатори на Oracle, въпреки че това наистина не е изяснено в документите. Тази статия на AskTom
препраща към него обаче чрез основния name_tokenize
процедура
:
Това не е свързано с обвързването или SQL Developer, това е ограничение на базата данни.
Можете да видите същия вид грешка, ако извикате dbms_utility.comma_to_table
процедура директно:
declare
arr dbms_utility.uncl_array;
len binary_integer;
begin
dbms_utility.comma_to_table('USER', len, arr);
end;
/
Error report -
ORA-20001: comma-separated list invalid near R
ORA-06512: at "SYS.DBMS_UTILITY", line 236
ORA-06512: at "SYS.DBMS_UTILITY", line 256
ORA-06512: at line 5
Или чрез извикване на dbms_utility.name_tokenize
директно:
declare
a varchar2(30);
b varchar2(30);
c varchar2(30);
d varchar2(30);
e binary_integer;
begin
dbms_utility.name_tokenize('USER', a, b, c, d, e);
end;
/
Error report -
ORA-00931: missing identifier
ORA-06512: at "SYS.DBMS_UTILITY", line 167
ORA-06512: at line 8
00931. 00000 - "missing identifier"
Не можете да използвате това, ако вашите стойности, разделени със запетая, са запазени думи
или не са разрешени като идентификатори по някаква друга причина; като се започне с число, например. Ще получите същия проблем, ако списъкът съдържа TABLE
или 42TAB
. Това всъщност не е предназначението му, както споменава Том.
Можете частично да заобиколите ограниченията, като принудите всички елементи да бъдат поставени в двойни кавички, което можете да направите с replace
. и тогава всеки от тези примери е разрешен:
declare
arr dbms_utility.uncl_array;
len binary_integer;
begin
dbms_utility.comma_to_table('"USER","TABLE","42TAB"', len, arr);
end;
/
anonymous block completed
Така че за вашия код, променете iv_raw
докато го предавате, и след това премахнете двойните кавички от всяка върната стойност:
FUNCTION comma_to_table(iv_raw IN VARCHAR2)
RETURN bind_tab_typ
PIPELINED
IS
ltab_lname dbms_utility.lname_array;
ln_len BINARY_INTEGER;
BEGIN
dbms_utility.comma_to_table(list => '"' || replace(iv_raw, ',', '","') || '"'
,tablen => ln_len
,tab => ltab_lname);
FOR i IN 1 .. ln_len LOOP
PIPE ROW (replace(ltab_lname(i), '"'));
END LOOP;
END comma_to_table;
Тогава това работи:
select * from table(ui_util.comma_to_table('USER,TABLE,42T'));
COLUMN_VALUE
--------------------
USER
TABLE
42T
Но все още сте ограничени до 30 знака или по-малко от всеки елемент, тъй като това е ограничение дори за идентификатори в кавички.