oracle substring returns 错误文本
oracle substring returns wrong text
运行returns错误文本时的功能如下。例子。 Table A 包含 msg_id 和 msg_text。 Table B 包含要解析的字符串。
出于某种原因,我能够从 Table B 中的字符串中正确提取所有 msg_id 的位置。如开始位置 2 结束位置 4。但是当涉及到实际提取时from table B string substr (result_val, strt,endstr) returns 文本太多或不够。它可能会向子字符串添加 space,或者可能会在末尾添加更多文本。但实际坐标与我需要提取的文本正确匹配。似乎 substr 取了一个不同的值..有什么想法吗?
具体来说,变量 "extracted" 显示了我正在寻找的正确 ID,但是当我尝试在任何地方找到该 ID 时,我得到了错误的结果。
这是我在 dual
中放置的内容
select ('@1 @2') from dual
Output:My comment for number 1 My comment for number 2
select (' @1 @2') from dual
Output: nothing
select ('@1') from dual
output: My comment for number 1
select result_parm(' @1') from dual;
output: My comment for number 1 --note it did add the space correctly
select result_parm(' @1 @2') from dual;
output: none
幕后的 DBMS 输出在解析时向我展示了以下内容
'@1 @2 @3'。我不得不注释掉替换部分,似乎那里有什么东西坏了,阻止了第二项之后的任何解析。
幕后 dbms 输出:
起始字符串 1
结束字符串 2
@1 <-- 用 substr 抓取了 @1,但它还在 1 之后抓取了一个额外的 space
开始字符串 4
结束字符串 5
@2 @3 <-- 为什么它抓错了@2 和@3 而位置明明是 4,5
我有一种感觉,这也是杀死替换的原因,但不确定为什么
开始字符串 7
结束字符串 8
@3 <--抓取正确
Tables:
create table REC_CANNED_COMM
(
ENTRY_NUM INTEGER not null,
MSG_ID VARCHAR2(5),
MSG_TEXT VARCHAR2(200)
);
create table REC_RESULT
(
ENTRY_NUM INTEGER not null,
RESULT_TXT VARCHAR2(200)
);
insert into rec_result values ('1','@1');
insert into rec_result values ('2','@1 and @2');
insert into rec_result values ('3','@1 and @2 and @3');
insert into rec_result values ('4','this is entry @4');
insert into rec_result values ('5','This one has no canned message');
insert into rec_canned_comm values ('1','@1','My comment for number 1');
insert into rec_canned_comm values ('2','@2','My comment for number 2');
insert into rec_canned_comm values ('3','@3','My comment for number 3');
insert into rec_canned_comm values ('4','@4','My comment for number 4');
insert into rec_canned_comm values ('5','@5','My comment for number 5');
CREATE OR REPLACE FUNCTION result_parm(result_val VARCHAR2)
RETURN VARCHAR2 IS
num NUMBER;
tmp VARCHAR2(2000);
strt NUMBER;
endstr NUMBER;
tmp_msg VARCHAR2(2000);
tmp_msg_txt VARCHAR2(2000);
extracted VARCHAR2(2000);
BEGIN
tmp := result_val;
num := regexp_count(result_val, '@');
IF (num = 0)
THEN RETURN result_val;
END IF;
FOR loop_count IN 1..num
LOOP
tmp_msg := '';
tmp_msg_txt := '';
strt := instr(result_val, '@', 1, loop_count);
endstr := CASE
WHEN regexp_instr(result_val,
'[\,\.\;\:\''\ <\>\/\+\-]|\s',
instr(result_val, '@', 1, loop_count)) = 0
THEN length(result_val)
WHEN regexp_instr(result_val,
'^[\,\.\;\:\''\<\>\/\+\-]|\s',
instr(result_val, '@', 1, loop_count)) > 0
THEN regexp_instr(result_val,
'^[\,\.\;\:\''\<\>\/\+\-]|\s',
instr(result_val, '@', 1, loop_count)) - 1
END;
dbms_output.put_line('start string ' || strt);
dbms_output.put_line('end string ' || endstr);
extracted := substr(result_val, strt, endstr);
dbms_output.put_line(extracted);
SELECT
rec_canned_comm.msg_id,
rec_canned_comm.msg_text
INTO tmp_msg,
tmp_msg_txt
FROM rec_canned_comm
WHERE rec_canned_comm.msg_id = extracted;
tmp := replace(tmp, tmp_msg, tmp_msg_txt);
END LOOP;
RETURN tmp;
END;
我不恰当地使用了 endstr。在 instr 或 substr 中看到 endstr 的地方应该是 (endstr - strt +1)。我使用的是位置而不是字符长度。这一切都不同了。
运行returns错误文本时的功能如下。例子。 Table A 包含 msg_id 和 msg_text。 Table B 包含要解析的字符串。
出于某种原因,我能够从 Table B 中的字符串中正确提取所有 msg_id 的位置。如开始位置 2 结束位置 4。但是当涉及到实际提取时from table B string substr (result_val, strt,endstr) returns 文本太多或不够。它可能会向子字符串添加 space,或者可能会在末尾添加更多文本。但实际坐标与我需要提取的文本正确匹配。似乎 substr 取了一个不同的值..有什么想法吗?
具体来说,变量 "extracted" 显示了我正在寻找的正确 ID,但是当我尝试在任何地方找到该 ID 时,我得到了错误的结果。
这是我在 dual
中放置的内容select ('@1 @2') from dual
Output:My comment for number 1 My comment for number 2
select (' @1 @2') from dual
Output: nothing
select ('@1') from dual
output: My comment for number 1
select result_parm(' @1') from dual;
output: My comment for number 1 --note it did add the space correctly
select result_parm(' @1 @2') from dual;
output: none
幕后的 DBMS 输出在解析时向我展示了以下内容 '@1 @2 @3'。我不得不注释掉替换部分,似乎那里有什么东西坏了,阻止了第二项之后的任何解析。
幕后 dbms 输出: 起始字符串 1 结束字符串 2 @1 <-- 用 substr 抓取了 @1,但它还在 1 之后抓取了一个额外的 space 开始字符串 4 结束字符串 5 @2 @3 <-- 为什么它抓错了@2 和@3 而位置明明是 4,5 我有一种感觉,这也是杀死替换的原因,但不确定为什么 开始字符串 7 结束字符串 8 @3 <--抓取正确
Tables:
create table REC_CANNED_COMM
(
ENTRY_NUM INTEGER not null,
MSG_ID VARCHAR2(5),
MSG_TEXT VARCHAR2(200)
);
create table REC_RESULT
(
ENTRY_NUM INTEGER not null,
RESULT_TXT VARCHAR2(200)
);
insert into rec_result values ('1','@1');
insert into rec_result values ('2','@1 and @2');
insert into rec_result values ('3','@1 and @2 and @3');
insert into rec_result values ('4','this is entry @4');
insert into rec_result values ('5','This one has no canned message');
insert into rec_canned_comm values ('1','@1','My comment for number 1');
insert into rec_canned_comm values ('2','@2','My comment for number 2');
insert into rec_canned_comm values ('3','@3','My comment for number 3');
insert into rec_canned_comm values ('4','@4','My comment for number 4');
insert into rec_canned_comm values ('5','@5','My comment for number 5');
CREATE OR REPLACE FUNCTION result_parm(result_val VARCHAR2)
RETURN VARCHAR2 IS
num NUMBER;
tmp VARCHAR2(2000);
strt NUMBER;
endstr NUMBER;
tmp_msg VARCHAR2(2000);
tmp_msg_txt VARCHAR2(2000);
extracted VARCHAR2(2000);
BEGIN
tmp := result_val;
num := regexp_count(result_val, '@');
IF (num = 0)
THEN RETURN result_val;
END IF;
FOR loop_count IN 1..num
LOOP
tmp_msg := '';
tmp_msg_txt := '';
strt := instr(result_val, '@', 1, loop_count);
endstr := CASE
WHEN regexp_instr(result_val,
'[\,\.\;\:\''\ <\>\/\+\-]|\s',
instr(result_val, '@', 1, loop_count)) = 0
THEN length(result_val)
WHEN regexp_instr(result_val,
'^[\,\.\;\:\''\<\>\/\+\-]|\s',
instr(result_val, '@', 1, loop_count)) > 0
THEN regexp_instr(result_val,
'^[\,\.\;\:\''\<\>\/\+\-]|\s',
instr(result_val, '@', 1, loop_count)) - 1
END;
dbms_output.put_line('start string ' || strt);
dbms_output.put_line('end string ' || endstr);
extracted := substr(result_val, strt, endstr);
dbms_output.put_line(extracted);
SELECT
rec_canned_comm.msg_id,
rec_canned_comm.msg_text
INTO tmp_msg,
tmp_msg_txt
FROM rec_canned_comm
WHERE rec_canned_comm.msg_id = extracted;
tmp := replace(tmp, tmp_msg, tmp_msg_txt);
END LOOP;
RETURN tmp;
END;
我不恰当地使用了 endstr。在 instr 或 substr 中看到 endstr 的地方应该是 (endstr - strt +1)。我使用的是位置而不是字符长度。这一切都不同了。