字符串文字的限制为4000字节。我决定建立一个表函数,将由逗号,冒号,分号或管道分开,并输出它作为一个列中的值。通常我会用regexp_replace来做这件事,但是没有clob数据类型的函数,对吗?有更好的方法吗?
如果传递一些值,函数将编译并工作。
我以为我能做这样的事
variable patrik clob;
exec :patrik := 'abc,ghj,yut';
select * from patrik_split_clob(:patrik)
SQL Developer再次打开一个弹出窗口输入值,我认为它可以使用刚刚分配的值的绑定变量并运行。
我也可以用这种方式,只是好奇。
存在另一个问题,并出现以下错误
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "PATRIK_SPLIT_CLOB", line 28
06502. 00000 - "PL/SQL: numeric or value error%s"
*Cause: An arithmetic, numeric, string, conversion, or constraint error
occurred. For example, this error occurs if an attempt is made to
assign the value NULL to a variable declared NOT NULL, or if an
attempt is made to assign an integer larger than 99 to a variable
declared NUMBER(2).
*Action: Change the data, how it is manipulated, or how it is declared so
that values do not violate constraints.
CREATE OR REPLACE TYPE patrik_split_value AS OBJECT (value VARCHAR2(4000));
CREATE OR REPLACE TYPE patrik_split_table AS TABLE OF patrik_split_value;
CREATE OR REPLACE FUNCTION patrik_split_clob(p_clob CLOB)
RETURN patrik_split_table
AS
v_result patrik_split_table := patrik_split_table();
v_start_pos NUMBER := 1;
v_end_pos NUMBER;
v_length NUMBER := DBMS_LOB.GETLENGTH(p_clob);
BEGIN
LOOP
v_end_pos := DBMS_LOB.INSTR(p_clob, ',', v_start_pos);
IF v_end_pos = 0 THEN
v_end_pos := DBMS_LOB.INSTR(p_clob, ':', v_start_pos);
END IF;
IF v_end_pos = 0 THEN
v_end_pos := DBMS_LOB.INSTR(p_clob, ';', v_start_pos);
END IF;
IF v_end_pos = 0 THEN
v_end_pos := DBMS_LOB.INSTR(p_clob, '|', v_start_pos);
END IF;
IF v_end_pos = 0 THEN
EXIT;
END IF;
v_result.EXTEND;
v_result(v_result.COUNT) := patrik_split_value(DBMS_LOB.SUBSTR(p_clob, v_end_pos - v_start_pos, v_start_pos));
v_start_pos := v_end_pos + 1;
END LOOP;
v_result.EXTEND;
v_result(v_result.COUNT) := patrik_split_value(DBMS_LOB.SUBSTR(p_clob, v_length - v_start_pos + 1, v_start_pos));
RETURN v_result;
END;
我做错了什么?$NUMBER应该处理99个以上,是因为v_start_pos:= 1吗?
2条答案
按热度按时间ki1q1bka1#
我做错了什么?
从字符串中给定的开始位置,您将找到
如果你有字符串
a|b;c:d,e
,那么你匹配的第一个分隔符将是逗号,第一个术语将是a|b;c:d
,第二个术语是e
;你不会在多个分隔符上分割字符串,除非它们都是按照,
然后:
然后;
然后|
的顺序。此外:
TABLE OF VARCHAR2(4000)
,或者如果每个术语可能大于4000字节,则可以使用TABLE OF CLOB
。这是我为earlier question创建的一个函数,它由一个分隔符分隔:
如果您想将其更改为多个分隔符(并确保每个术语将为4000个字符或更少),则:
然后:
输出:
| 列值|
| --------------|
| ABC|
| ghj|
| 尤特|
以及:
输出:
| 列值|
| --------------|
| 一种|
| B|
| c|
| d|
| e|
SELECT * FROM TABLE(split_clob(:varaible))
,但在更高版本中,表集合表达式语法是可选的,可以省略(正如您所做的那样)。*fiddle
6ie5vjzr2#
这或多或少是好的,你只是叫它在一个错误的方式。