Het probleem is dat de dbms_utility.comma_to_table
procedure
vereist dat de elementen van de lijst geldige Oracle-ID's zijn, hoewel dat niet echt duidelijk wordt gemaakt in de documenten. Dit AskTom-artikel
verwijst er echter naar, via de onderliggende name_tokenize
procedure
:
Het heeft niets te maken met de binding of SQL Developer, het is een databasebeperking.
U kunt dezelfde soort fout zien als u de dbms_utility.comma_to_table
aanroept procedure direct:
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
Of door dbms_utility.name_tokenize
. te bellen rechtstreeks:
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"
U kunt dit niet gebruiken als uw door komma's gescheiden waarden gereserveerde woorden
of zijn om een andere reden niet toegestaan als identifiers; beginnend met een getal, bijvoorbeeld. U zou hetzelfde probleem krijgen als de lijst TABLE
. zou bevatten of 42TAB
. Dit is niet echt waar het voor bedoeld is, zoals Tom zegt.
Je kunt de beperkingen gedeeltelijk omzeilen door alle elementen dubbel te citeren, wat je zou kunnen doen met een replace
. en dan is elk van deze voorbeelden toegestaan:
declare
arr dbms_utility.uncl_array;
len binary_integer;
begin
dbms_utility.comma_to_table('"USER","TABLE","42TAB"', len, arr);
end;
/
anonymous block completed
Dus voor uw code, wijzig iv_raw
terwijl u het doorgeeft, en verwijder vervolgens de dubbele aanhalingstekens van elke geretourneerde waarde:
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;
Dan werkt dit:
select * from table(ui_util.comma_to_table('USER,TABLE,42T'));
COLUMN_VALUE
--------------------
USER
TABLE
42T
Maar je bent nog steeds beperkt tot elk element van 30 tekens of minder, aangezien dat een beperking is voor zelfs tussen aanhalingstekens identifiers.