sql >> Databasteknik >  >> RDS >> Oracle

lista för att binda variabel i SQL Developer

Problemet är att dbms_utility .comma_to_table förfarande kräver att elementen i listan är giltiga Oracle-identifierare, även om det egentligen inte framgår av dokumenten. Denna AskTom-artikel hänvisar dock till det via den underliggande name_tokenize förfarande :

Det har inte att göra med bindningen eller SQL-utvecklaren, det är en databasbegränsning.

Du kan se samma typ av fel om du anropar dbms_utility.comma_to_table procedur 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

Eller genom att anropa 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"

Du kan inte använda detta om dina kommaseparerade värden är reserverade ord eller är inte tillåtna som identifierare av någon annan anledning; börjar med en siffra, till exempel. Du skulle få samma problem om listan innehöll TABELL eller 42TAB . Det är inte riktigt vad den är avsedd för, som Tom nämner.

Du kan delvis komma runt begränsningarna genom att tvinga alla element att vara dubbla citattecken, vilket du kan göra med en ersätt . och sedan är något av dessa exempel tillåtna:

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å för din kod, ändra iv_raw när du skickar över det och ta sedan bort de dubbla citattecken från varje returnerat värde:

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;

Då fungerar detta:

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

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

Men du är fortfarande begränsad till att varje element är 30 tecken eller mindre, eftersom det är en begränsning för även citerade identifierare.




  1. MySQL:s MD5-hash är felaktig

  2. RowGen v3 automatiserar generering av databastestdata

  3. Kontrollera strängens språk baserat på glyfer i PHP

  4. Konvertera icke-partitionstabell till partitionerad tabell med ONLINE i Oracle PL/SQL