問題は、dbms_utilityです。 .comma_to_table
手順
リストの要素は有効なOracle識別子である必要がありますが、実際にはドキュメントでは明確にされていません。 このAskTomの記事
ただし、基礎となる<を介して参照します。 code> name_tokenize 手順
:
バインディングやSQLDeveloperとは関係ありません。これは、データベースの制限です。
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文字以下に制限されています。