Oracle
 sql >> Baza danych >  >> RDS >> Oracle

lista do powiązania zmiennej w SQL Developer

Problem polega na tym, że dbms_utility.comma_to_table procedura wymaga, aby elementy listy były prawidłowymi identyfikatorami Oracle, chociaż tak naprawdę nie jest to wyjaśnione w dokumentacji. Ten artykuł AskTom odnosi się do niego jednak, za pośrednictwem podstawowego name_tokenize procedura :

Nie ma to nic wspólnego z wiązaniem lub SQL Developerem, to ograniczenie bazy danych.

Możesz zobaczyć ten sam rodzaj błędu, jeśli wywołasz dbms_utility.comma_to_table procedura bezpośrednio:

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

Lub dzwoniąc do dbms_utility.name_tokenize bezpośrednio:

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"

Nie możesz tego użyć, jeśli Twoje wartości oddzielone przecinkami to słowa zastrzeżone lub nie są dozwolone jako identyfikatory z innego powodu; na przykład zaczynając od numeru. Otrzymasz ten sam problem, jeśli lista zawiera TABLE lub 42TAB . To nie jest to, do czego jest przeznaczony, jak wspomina Tom.

Możesz częściowo obejść ograniczenia, zmuszając wszystkie elementy do podwójnego cudzysłowu, co możesz zrobić za pomocą replace . a następnie dowolny z tych przykładów jest dozwolony:

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

anonymous block completed

Więc dla swojego kodu zmodyfikuj iv_raw w miarę jej przekazywania, a następnie usuwaj podwójne cudzysłowy z każdej zwracanej wartości:

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;

Wtedy to działa:

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

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

Ale nadal jesteś ograniczony do tego, że każdy element ma 30 znaków lub mniej, ponieważ jest to ograniczenie nawet dla identyfikatorów cytowanych.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ORACLE Connect by równoważna klauzula w SQL Server

  2. Generuj i wstawiaj duże pliki CLOB (1 MB) za pomocą SQL*Plus

  3. Funkcja NLSSORT() w Oracle

  4. Czy Oracle wycofuje transakcję w przypadku błędu?

  5. Czy mogę wykonać atomowe MERGE w Oracle?