Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Liste zum Binden der Variablen in SQL Developer

Das Problem ist, dass das dbms_utility .comma_to_table Verfahren erfordert, dass die Elemente der Liste gültige Oracle-Bezeichner sind, obwohl dies in der Dokumentation nicht wirklich klargestellt wird. Dieser AskTom-Artikel verweist jedoch über den zugrunde liegenden name_tokenize Verfahren :

Es hat nichts mit der Bindung oder dem SQL Developer zu tun, es ist eine Datenbankeinschränkung.

Sie können die gleiche Art von Fehler sehen, wenn Sie dbms_utility.comma_to_table aufrufen Verfahren direkt:

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

Oder durch Aufruf von dbms_utility.name_tokenize direkt:

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"

Sie können dies nicht verwenden, wenn Ihre durch Kommas getrennten Werte reservierte Wörter oder aus anderen Gründen nicht als Bezeichner zulässig sind; beginnend mit einer Zahl, zum Beispiel. Sie würden das gleiche Problem bekommen, wenn die Liste TABLE enthalten würde oder 42TAB . Das ist nicht wirklich das, wofür es gedacht ist, wie Tom erwähnt.

Sie können die Einschränkungen teilweise umgehen, indem Sie erzwingen, dass alle Elemente in doppelte Anführungszeichen gesetzt werden, was Sie mit einem replace tun könnten . und dann sind alle diese Beispiele erlaubt:

declare
  arr dbms_utility.uncl_array;
  len binary_integer;
begin
  dbms_utility.comma_to_table('"USER","TABLE","42TAB"', len, arr);
end;
/

anonymous block completed

Ändern Sie also für Ihren Code iv_raw während Sie es übergeben, und entfernen Sie dann die doppelten Anführungszeichen von jedem zurückgegebenen Wert:

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;

Dann funktioniert das:

select * from table(ui_util.comma_to_table('USER,TABLE,42T'));

COLUMN_VALUE
--------------------
USER
TABLE
42T

Aber Sie sind immer noch darauf beschränkt, dass jedes Element 30 Zeichen oder weniger hat, da dies eine Einschränkung für Bezeichner in Anführungszeichen ist.