提取带有字符串引用问题的字符串 pl sql

Posted

技术标签:

【中文标题】提取带有字符串引用问题的字符串 pl sql【英文标题】:extract a string with a string quote issue pl sql 【发布时间】:2015-01-26 10:54:19 【问题描述】:

我使用下面的函数从输入中的字符串中提取字符串,问题是当我将字符串字符与字符串引号一起放入时,我无法提取它 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;

【问题讨论】:

我不确定你在问什么 - 你是说当字符串中有单引号时不能将字符串传递给函数,还是说函数的输出是不正确的?请详细说明您遇到的问题。 嗨,我的意思是当输入字符串中有单引号时,函数的输出不正确 以何种方式不正确?您期望看到什么以及实际输出什么? 您的计数和偏移逻辑似乎很混乱;您是说这适用于没有引号的值吗?我不明白它怎么可能。 我意识到这可能是一项家庭作业,但如果不是,您可能想知道Oracle supplies the INSTR function 完成了您似乎正在尝试执行的相同任务。祝你好运。 【参考方案1】:

对于您显示的示例字符串,您的代码中的子字符串偏移量和计数器调整已关闭。这可以提取任何“标签”:

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 所提到的,还有其他方法可以实现这种细分,但这甚至超出了您所询问的范围。

【讨论】:

【参考方案2】:

当您在字符串文字中嵌入了单引号时,您试图将其传递给函数或过程,您需要将其加倍(即键入两个单引号而不是一个),以便 PL/SQL 解释它正确。如您所愿,加倍的单引号将作为一个单引号发送到函数,但这是在 PL/SQL 中处理文字中的单引号的方式。因此,而不是将您的函数称为

n := get_string ('AB', 
                 'AA015streetl'adeuilAB00201AC0041234AD012XXXXXXXXXXXXAE009TTTTTTTTT', 
                 p_len,
                 p_value );

你应该把第二个参数中的单引号加倍:

n := get_string ('AB', 
                 'AA015streetl''adeuilAB00201AC0041234AD012XXXXXXXXXXXXAE009TTTTTTTTT', 
                 p_len,
                 p_value );

如果您从文件或其他外部来源读取输入,则不必这样做;仅当字符串 literal 中包含单引号时才需要。

分享和享受。

【讨论】:

以上是关于提取带有字符串引用问题的字符串 pl sql的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL:带有 UTF8 字符串的 UTL_HTTP POST 导致字符损坏

使用 PL SQL 提取基于属性的 XML

在 PL/SQL 中动态声明变量

Oracle PL/SQL 中的字符编码问题

PL/SQL 将字符串转换为布尔值

如何在 Pl/SQL 中编写正则表达式匹配模式?