Oracle SQL Developer中绑定变量的列表

Oracle SQL Developer中绑定变量的列表,oracle,plsql,Oracle,Plsql,我有一个函数,它获取元素列表并将它们放入表中,这样列表就可以用作绑定变量。一切正常,除了当我在列表用户中作为一个元素给出时,似乎Sql Developer进行了一些解析并导致了一些ORA-20001:T附近逗号分隔列表无效,使用错误。您知道是否可以为此添加一个变通方法,以便该函数也可以与USER元素一起使用吗 职能: FUNCTION comma_to_table(iv_raw IN VARCHAR2) RETURN bind_tab_typ PIPELINED IS

我有一个函数,它获取元素列表并将它们放入表中,这样列表就可以用作绑定变量。一切正常,除了当我在列表
用户
中作为一个元素给出时,似乎Sql Developer进行了一些解析并导致了一些
ORA-20001:T附近逗号分隔列表无效,使用
错误。您知道是否可以为此添加一个变通方法,以便该函数也可以与
USER
元素一起使用吗

职能:

  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   => iv_raw
                                ,tablen => ln_len
                                ,tab    => ltab_lname);
     FOR i IN 1 .. ln_len LOOP
        PIPE ROW (ltab_lname(i));
     END LOOP;
  END comma_to_table;
下面是测试它的查询:

select * from table(ui_util.comma_to_table(:myList))
如果我为myList设置了
测试、支持、USERT
,那么它工作得很好。如果我将其更改为
TEST,SUPPORT,USER
,则会出现上述错误。有什么建议吗?

问题在于需要列表中的元素是有效的Oracle标识符,尽管文档中没有明确说明这一点。尽管如此,通过基础的:

请注意,您不必使用真实的对象名(这些表和 过程不必存在),但必须使用有效的对象 标识符。如果未使用有效的对象标识符, NAME\u TOKENIZE将引发错误

这与绑定或SQL开发人员无关,而是数据库限制

如果直接调用
dbms\u实用程序.comma\u to\u 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
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"
或者直接调用
dbms\u实用程序.name\u tokenize

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
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
,则会出现同样的问题。正如汤姆提到的,这并不是它真正的目的

您可以通过强制将所有元素双引号来部分绕过限制,这可以通过
替换
来实现。然后这些例子中的任何一个都是允许的:

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个字符或更少,因为这是对连引号的标识符的限制。

问题在于,要求列表中的元素是有效的Oracle标识符,尽管文档中没有明确说明这一点。尽管如此,通过基础的:

请注意,您不必使用真实的对象名(这些表和 过程不必存在),但必须使用有效的对象 标识符。如果未使用有效的对象标识符, NAME\u TOKENIZE将引发错误

这与绑定或SQL开发人员无关,而是数据库限制

如果直接调用
dbms\u实用程序.comma\u to\u 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
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"
或者直接调用
dbms\u实用程序.name\u tokenize

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
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
,则会出现同样的问题。正如汤姆提到的,这并不是它真正的目的

您可以通过强制将所有元素双引号来部分绕过限制,这可以通过
替换
来实现。然后这些例子中的任何一个都是允许的:

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个字符或更少,因为这是对连引号的标识符的限制。

返回的“bind\u tab\u typ”是什么类型?返回的“bind\u tab\u typ”是什么类型?