sql >> Database teknologi >  >> RDS >> Oracle

liste for at binde variabel i SQL Developer

Problemet er, at dbms_utility.comma_to_table procedure kræver, at listens elementer er gyldige Oracle-identifikatorer, selvom det egentlig ikke er tydeliggjort i dokumenterne. Denne AskTom-artikel henviser dog til det via den underliggende >name_tokenize procedure :

Det har ikke at gøre med bindingen eller SQL-udvikleren, det er en databaserestriktion.

Du kan se den samme type fejl, hvis du kalder dbms_utility.comma_to_table procedure direkte:

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

Eller ved at kalde dbms_utility.name_tokenize direkte:

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"

Du kan ikke bruge dette, hvis dine kommaseparerede værdier er reserverede ord eller er ikke tilladt som identifikatorer af en eller anden grund; begyndende med et tal, for eksempel. Du ville få det samme problem, hvis listen indeholdt TABLE eller 42TAB . Det er egentlig ikke det, den er beregnet til, som Tom nævner.

Du kan delvist omgå begrænsningerne ved at tvinge alle elementer til at blive citeret i dobbelte citater, hvilket du kunne gøre med en replace . og så er alle disse eksempler tilladt:

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

anonymous block completed

Så for din kode skal du ændre iv_raw efterhånden som du sender det videre, og fjern derefter de dobbelte anførselstegn fra hver returnerede værdi:

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;

Så virker dette:

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

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

Men du er stadig begrænset til, at hvert element må være på 30 tegn eller mindre, da det er en begrænsning for selv citerede identifikatorer.




  1. Måling af PostgreSQL Checkpoint Statistik

  2. Oracle Konverter rækker til kolonner

  3. Hvordan eksporterer jeg SQL Server-database til MySQL?

  4. python mysqldb fejl på min mac:Bibliotek ikke indlæst:@rpath/libmysqlclient.21.dylib