Vấn đề là dbms_utility.comma_to_table
thủ tục
yêu cầu các phần tử của danh sách phải là số nhận dạng Oracle hợp lệ, mặc dù điều đó thực sự không được làm rõ trong tài liệu. Bài viết AskTom này
đề cập đến nó, thông qua name_tokenize
thủ tục
:
Nó không liên quan đến ràng buộc hoặc SQL Developer, đó là một hạn chế cơ sở dữ liệu.
Bạn có thể gặp cùng một loại lỗi nếu bạn gọi dbms_utility.comma_to_table
thủ tục trực tiếp:
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
Hoặc bằng cách gọi dbms_utility.name_tokenize
trực tiếp:
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"
Bạn không thể sử dụng điều này nếu các giá trị được phân tách bằng dấu phẩy của bạn là từ dành riêng
hoặc không được phép làm số nhận dạng vì một số lý do khác; bắt đầu bằng một số chẳng hạn. Bạn sẽ gặp vấn đề tương tự nếu danh sách chứa TABLE
hoặc 42TAB
. Đây thực sự không phải là mục đích của nó, như Tom đã đề cập.
Bạn có thể giải quyết một phần các hạn chế bằng cách buộc tất cả các phần tử phải được đặt trong dấu ngoặc kép, điều này bạn có thể làm với replace
. và sau đó bất kỳ ví dụ nào trong số đó đều được phép:
declare
arr dbms_utility.uncl_array;
len binary_integer;
begin
dbms_utility.comma_to_table('"USER","TABLE","42TAB"', len, arr);
end;
/
anonymous block completed
Vì vậy, đối với mã của bạn, hãy sửa đổi iv_raw
khi bạn chuyển nó qua, rồi xóa dấu ngoặc kép khỏi mỗi giá trị được trả về:
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;
Sau đó, điều này hoạt động:
select * from table(ui_util.comma_to_table('USER,TABLE,42T'));
COLUMN_VALUE
--------------------
USER
TABLE
42T
Nhưng bạn vẫn bị hạn chế đối với mỗi phần tử là 30 ký tự trở xuống, vì đó là hạn chế đối với các số nhận dạng được trích dẫn thậm chí.