我使用下面的函数从输入中的字符串中提取字符串,问题是当我把字符串字符与字符串引用时我无法提取它 exp作为输入:
AA015streetl'adeuilAB00201AC0041234AD012XXXXXXXXXXXXAE009TTTTTTTTT
FUNCTION get_string (p_name IN VARCHAR2,
p_strg IN VARCHAR2,
p_len OUT NOCOPY PLS_INTEGER,
p_value OUT NOCOPY VARCHAR2)
RETURN PLS_INTEGER
IS
v_counter PLS_INTEGER := 1;
v_strg VARCHAR2 (4096) := SUBSTR (p_strg, 5);
BEGIN
p_value := NULL;
p_len := 0.;
WHILE v_counter < LENGTH (v_strg)
LOOP
IF SUBSTR (v_strg, v_counter, 3.) = p_name
THEN
p_len :=
TO_NUMBER (SUBSTR (v_strg, v_counter + 3., 3.));
p_value :=
SUBSTR (v_strg, v_counter + 6., p_len);
RETURN (declaration_cst.ok);
END IF;
v_counter :=
v_counter
+ 6.
+ TO_NUMBER (SUBSTR (v_strg, v_counter + 3., 3.));
END LOOP;
RETURN (declaration_cst.nok);
END;
END get_string;
答案 0 :(得分:3)
对于您显示的示例字符串,代码中的子字符串偏移和计数器调整已关闭。这可以提取任何“标签”:
CREATE OR REPLACE FUNCTION get_string (p_name IN VARCHAR2, p_strg IN VARCHAR2,
p_len OUT NOCOPY PLS_INTEGER, p_value OUT NOCOPY VARCHAR2)
RETURN PLS_INTEGER IS
v_counter PLS_INTEGER := 1;
BEGIN
p_value := NULL;
p_len := 0;
WHILE v_counter < LENGTH (p_strg)
LOOP
IF SUBSTR (p_strg, v_counter, 2) = p_name
THEN
p_len := TO_NUMBER (SUBSTR (p_strg, v_counter + 2, 3));
p_value := SUBSTR (p_strg, v_counter + 5, p_len);
RETURN declaration_cst.ok;
END IF;
v_counter := v_counter + 5
+ TO_NUMBER (SUBSTR (p_strg, v_counter + 2, 3));
END LOOP;
RETURN declaration_cst.nok;
END get_string;
/
您的版本在v_strg
作业中完全丢失了前四个字符,然后进行调整,好像标记是三个字符,而不是两个字符。
使用类似的测试块:
set serveroutput on size unlimited
declare
str varchar2(256) := q'[AA015street l'adeuilAB00201AC0041234AD012XXXXXXXXXXXXAE009TTTTTTTTT]';
len pls_integer;
value varchar2(256);
rc pls_integer;
begin
rc := get_string('AB', str, len, value);
dbms_output.put_line('AB -> ' || rc ||':'|| len ||':'|| value);
end;
/
并更改“AB”标记:
AA -> 0:15:street l'adeuil
AB -> 0:2:01
AC -> 0:4:1234
AD -> 0:12:XXXXXXXXXXXX
AE -> 0:9:TTTTTTTTT
AF -> 1:0:
带有包装函数的SQL Fiddle demo,因此可以更轻松地显示提取的标签信息。
如果字符串值包含单引号,则没有任何区别,只要标记长度正确 - 它只是substr的另一个字符,并且不会以任何不同的方式进行解释。
正如Bob Jarvis所说,还有其他方法可以实现这一细分,但这甚至超出了你所要求的范围。
答案 1 :(得分:2)
当您在字符串文字中嵌入单引号时,您试图传递给函数或过程,您需要将其加倍(即键入两个单引号而不是一个),以便PL / SQL正确解释它。如你想要的那样,doubled单引号将作为一个单引号发送给函数,但这就是在PL / SQL中处理文字中单引号的方式。因此,而不是将您的函数称为
n := get_string ('AB',
'AA015streetl'adeuilAB00201AC0041234AD012XXXXXXXXXXXXAE009TTTTTTTTT',
p_len,
p_value );
你应该在第二个参数中加倍单引号:
n := get_string ('AB',
'AA015streetl''adeuilAB00201AC0041234AD012XXXXXXXXXXXXAE009TTTTTTTTT',
p_len,
p_value );
如果您正在阅读文件或其他外部来源的输入,则您不必这样做;仅当字符串 literal 中包含单引号时才需要它。
分享并享受。