【问题标题】:regex for oracle "create procedure" definitionoracle“创建过程”定义的正则表达式
【发布时间】:2016-06-09 13:46:09
【问题描述】:

我需要正则表达式来捕获完整的“创建过程”语句。

这是我用来测试正则表达式的示例之一:

CREATE OR REPLACE PROCEDURE sp_for_comp (P_VARNAME IN VARCHAR2, P_VALUE IN OUT NUMBER)
   as
   v_if_exists NUMBER(10,0);
BEGIN
   SELECT   COUNT(*) INTO v_if_exists FROM PKG_VAR WHERE VARIABLENAME = P_VARNAME;
   IF v_if_exists > 0
   THEN
      begin
         SELECT VALUE INTO P_VALUE FROM PKG_VAR WHERE VARIABLENAME = P_VARNAME;
         EXCEPTION
         WHEN OTHERS THEN
            NULL;
      end;
ELSE
      begin
         INSERT INTO PKG_VAR  VALUES(P_VARNAME, P_VALUE);
         EXCEPTION
         WHEN OTHERS THEN
            NULL;
      end;
   END IF;
END;
/

当前正则表达式:

/CREATE\s+(OR\s+REPLACE\s+)?PROCEDURE\s+(\w+)\s*\(((?!.*\bEND\b\s*(\w+\s*)?\;\s*\/).*\s*)+.+/

至于我的问题:我使用 QRegularExpression 类,当我在大文件上运行它时程序失败。此外,当我在小文件上运行它时 - 一切正常。

在 regexr.com 等在线调试器上进行了大量测试后,我在 regex 中找不到问题。

我应该如何改变它,哪里可能有问题?

【问题讨论】:

  • regex 可能是一个很好的查找工具,但是解析复杂的代码,无论是htmlsql 还是其他,都不应该用它来完成。如果你在声明中定义一个方法会发生什么,你需要重写整个正则表达式,它会很快变得不可读,而且它不可维护,并且可能导致几个“错误”。
  • 试试CREATE\s+(OR\s+REPLACE\s+)?PROCEDURE\s+(\w+)\s*\([^\n]+(?:\n(?!END;\n)[^\n]*)*\nEND;。它基于展开循环技术,应该更有效。请注意,由于您在前瞻部分中检查 .*,因此您的回火正则表达式令牌已损坏。如果它有效,我会发布解释。

标签: sql regex oracle regex-lookarounds


【解决方案1】:

尝试一些非常简单的方法,例如:

CREATE(\s+OR\s+REPLACE)\s+PROCEDURE.*?END;\s*/

它只是在开头查找CREATE OR REPLACE PROCEDURE,然后在下一行查找END;,然后是/(表示SQL 范围内PL/SQL 块的结尾)之间的金额。

(注意:您可能希望使用ni 正则表达式匹配参数来允许. 匹配换行符并进行不区分大小写的匹配。)

示例

CREATE TABLE script (value ) AS
SELECT  'CREATE OR REPLACE PROCEDURE sp_for_comp (P_VARNAME IN VARCHAR2, P_VALUE IN OUT NUMBER)' || CHR(10)
        || '   as' || CHR(10)
        || '   v_if_exists NUMBER(10,0);' || CHR(10)
        || 'BEGIN' || CHR(10)
        || '   SELECT   COUNT(*) INTO v_if_exists FROM PKG_VAR WHERE VARIABLENAME = P_VARNAME;' || CHR(10)
        || '   IF v_if_exists > 0' || CHR(10)
        || '   THEN' || CHR(10)
        || '      begin' || CHR(10)
        || '         SELECT VALUE INTO P_VALUE FROM PKG_VAR WHERE VARIABLENAME = P_VARNAME;' || CHR(10)
        || '         EXCEPTION' || CHR(10)
        || '         WHEN OTHERS THEN' || CHR(10)
        || '            NULL;' || CHR(10)
        || '      end;' || CHR(10)
        || 'ELSE' || CHR(10)
        || '      begin' || CHR(10)
        || '         INSERT INTO PKG_VAR  VALUES(P_VARNAME, P_VALUE);' || CHR(10)
        || '         EXCEPTION' || CHR(10)
        || '         WHEN OTHERS THEN' || CHR(10)
        || '            NULL;' || CHR(10)
        || '      end;' || CHR(10)
        || '   END IF;' || CHR(10)
        || 'END;' || CHR(10)
        || '/'
FROM DUAL;

SELECT COUNT(*)
FROM   script
WHERE  REGEXP_LIKE( value, '^CREATE(\s+OR\s+REPLACE)\s+PROCEDURE.*?END;\s*/$', 'n' );

输出

COUNT(*)
--------
       1

【讨论】:

    猜你喜欢
    • 2017-06-16
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-05
    • 2010-10-01
    相关资源
    最近更新 更多