在PL-SQL中,我想将两列中的两个字符串(地址行1,地址行2,每行最多45个字符)连接成3个字符串(地址行1,地址行2,地址行3,最大值34)每个字符都基于不应该在中间剪切的条件。例如:
如果地址行1包含:
1, abc park, def chowk, ghi marg c-123 street
和地址第2行包含:
city mumbai, pin - 435353
结合编号显示34个字符落在哪处:
1111111111222222222233333 1111111111222222222233333
12345678901234567890123456789012341234567890123456789012345678901234123
1, abc park, def chowk, ghi marg c-123 street city mumbai, pin - 435353
结果应该是这样的
Add1(最多34个字符):
1, abc park, def chowk, ghi marg
Add2(最多34个字符):
c-123 street city mumbai,
Add3(最多34个字符):
pin - 435353
答案 0 :(得分:1)
我有同样的问题,我写了这个函数,它将文本分成固定长度的行而不截断单词。
pi_text:您的解包文字
pi_max_line:您要拆分的行长
CREATE OR REPLACE FUNCTION wrap_to_paragraph(pi_text VARCHAR2,
pi_max_line PLS_INTEGER,
pi_end_paragraph VARCHAR2 DEFAULT CHR(10)) RETURN VARCHAR2 IS
TYPE paragraph_tabletype_aat IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;
l_loc_para paragraph_tabletype_aat;
l_loc_lines INTEGER;
l_return VARCHAR2(32767);
PROCEDURE to_paragraph(pi_text_in IN VARCHAR2,
pi_line_length IN INTEGER,
po_paragraph_out IN OUT paragraph_tabletype_aat,
pio_num_lines_out IN OUT INTEGER,
pi_word_break_at_in IN VARCHAR2 := ' ') IS
l_len_text INTEGER := LENGTH(pi_text_in);
l_line_start_loc INTEGER := 1;
l_line_end_loc INTEGER := 1;
l_last_space_loc INTEGER;
l_curr_line VARCHAR2(100);
l_replace_string VARCHAR2(100) := NULL;
PROCEDURE set_replace_string IS
BEGIN
l_replace_string := RPAD('@', LENGTH(pi_word_break_at_in), '@');
END set_replace_string;
PROCEDURE find_last_delim_loc(pi_line_in IN VARCHAR2,
po_loc_out OUT INTEGER) IS
l_line VARCHAR2(1000) := pi_line_in;
BEGIN
IF pi_word_break_at_in IS NOT NULL
THEN
l_line := translate(pi_line_in, pi_word_break_at_in, l_replace_string);
END IF;
po_loc_out := INSTR(l_line, '@', -1);
END find_last_delim_loc;
BEGIN
set_replace_string;
IF l_len_text IS NULL
THEN
pio_num_lines_out := 0;
ELSE
pio_num_lines_out := 1;
LOOP
EXIT WHEN l_line_end_loc > l_len_text;
l_line_end_loc := LEAST(l_line_end_loc + pi_line_length, l_len_text + 1);
/* get the next possible line of text */
l_curr_line := SUBSTRB(pi_text_in || ' ', l_line_start_loc, pi_line_length + 1);
/* find the last space in this section of the line */
find_last_delim_loc(l_curr_line, l_last_space_loc);
/* When NO spaces exist, use the full current line*/
/* otherwise, cut the line at the space. */
IF l_last_space_loc > 0
THEN
l_line_end_loc := l_line_start_loc + l_last_space_loc;
END IF;
IF INSTR(l_curr_line, pi_end_paragraph) > 0
THEN
l_line_end_loc := l_line_start_loc + INSTR(l_curr_line, pi_end_paragraph) + 1;
END IF;
/* Add this line to the paragraph */
po_paragraph_out(pio_num_lines_out) := REPLACE(SUBSTRB(pi_text_in,
l_line_start_loc,
l_line_end_loc - l_line_start_loc),
pi_end_paragraph);
pio_num_lines_out := pio_num_lines_out + 1;
l_line_start_loc := l_line_end_loc;
END LOOP;
pio_num_lines_out := pio_num_lines_out - 1;
END IF;
END to_paragraph;
BEGIN
/* Return original */
IF (pi_max_line = 0 OR pi_max_line > 99)
THEN
RETURN pi_text;
END IF;
/* Build each paragraph in record */
to_paragraph(pi_text, pi_max_line, l_loc_para, l_loc_lines);
/* Extract Result */
FOR i IN 1 .. l_loc_lines
LOOP
l_return := l_return || l_loc_para(i) || pi_end_paragraph;
END LOOP;
RETURN TRIM(CHR(10) FROM l_return);
END wrap_to_paragraph;
答案 1 :(得分:0)
REGEXP_SUBSTR()可用于为您解决此问题。正如我在您对原始帖子的评论中所说的那样,您的文字说不要破坏一个字,但是您的示例显示ADD3在最后一个逗号/空格后突破,而不仅仅是空格,因此您需要进一步定义规则(也许当它只是最后一个逗号之后的最后一节?)。无论如何,坚持你写的东西,正则表达式给出第一次,第二次或第三次出现最多34个字符,后跟一个不是空格的字符,后跟一个空格字符或行的结尾。
SQL> with tbl(addr) as (
select '1, abc park, def chowk, ghi marg c-123 street city mumbai, pin - 435353'
from dual
)
select regexp_substr(addr, '(.{0,34}\S)(\s|$)', 1, 1) add1,
regexp_substr(addr, '(.{0,34}\S)(\s|$)', 1, 2) add2,
regexp_substr(addr, '(.{0,34}\S)(\s|$)', 1, 3) add3
from tbl;
ADD1 ADD2 ADD3
--------------------------------- -------------------------------- ------
1, abc park, def chowk, ghi marg c-123 street city mumbai, pin - 435353
SQL>