科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道DB2中如何实现正则表达式

DB2中如何实现正则表达式

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文描述了如何实现一个用户定义函数(UDF),该函数将普遍可用的正则表达式匹配库与 DB2 集成在一起。我们通过示例使用了 pcre 库,但也可以用任何其它库替换它。

来源:IT专家网 2008年6月10日

关键字: IBM 数据库 DB2

  • 评论
  • 分享微博
  • 分享邮件

实现模式匹配函数
您可以使用 DB2 的可扩展机制,在 SQL 语句内使用 UDF,以便显著地改善这种情形。通过定义名为 regex1 的 UDF(它采用模式和字符串作为输入参数), 清单 1中的 WHERE 子句现在可以写得象 清单 3中所示的那样:

清单 3. 使用 regex UDF 来简化模式匹配


SELECT str
FROM   strTable
WHERE regex1('\\w* = (\\d|0x00);', str) = 1

在本示例中,使用带有 Perl 扩展的正则表达式来匹配完整的模式,而不仅仅是 清单 1中给出的 LIKE 谓词所对应的部分模式。正如您所看到的,使用函数来为该模式编写谓词比用 LIKE 谓词表示同样的语义要容易得多。

实现 UDF
在我的示例实现中,我选择了现有的名为 PCRE(Perl 兼容的正则表达式,Perl-compatible regular expression)的模式匹配引擎。该引擎提供了用来处理模式和执行匹配的 C API。该引擎和查询中所用的 SQL 语言之间“缺失的部分”是 UDF。该 UDF 由两部分组成:

* 在数据库中创建(或注册)该函数的 CREATE FUNCTION 语句。
* 该函数的主体,它实现了用于正则表达式匹配引擎的 C API 调用的封装器

清单 4显示了用于创建该函数的 SQL 语句。

清单 4. 注册 regex1 函数


CREATE FUNCTION regex1(pattern VARCHAR(2048), string CLOB(10M))
    RETURNS INTEGER
    SPECIFIC regexSimple
    EXTERNAL NAME 'regexUdf!regexpSimple'
    LANGUAGE C
    PARAMETER STYLE DB2SQL
    DETERMINISTIC
    NOT FENCED
    RETURNS NULL ON NULL INPUT
    NO SQL
    NO EXTERNAL ACTION
    ALLOW PARALLEL;

注:请参阅 DB2 SQL Reference以获取所有子句的详细含义。可以修改参数的长度以适应您的需求。我在此处展示某些值并没有任何推荐使用它们的用意。

第二部分由一小段 C 代码组成,它实现了 UDF 入口点。在查询执行期间,DB2 为每个要与模式匹配的行调用这个入口点。 清单 5中的示例列出了该代码的清单。有关 pcre_* 函数和宏的描述,请参考 PCRE 库的文档。有关 C 代码的编译和共享库的构建,请参考 DB2 Application Development Guide

清单 5. 实现 rege1x UDF 入口点的 C 代码


#include <pcre.h>
#include <sqludf.h>

void regexpSimple(
    // input parameters
    SQLUDF_VARCHAR *pattern,      SQLUDF_CLOB *str,
    // output
    SQLUDF_INTEGER *match,
    // null indicators
    SQLUDF_NULLIND *pattern_ind,  SQLUDF_NULLIND *str_ind,
    SQLUDF_NULLIND *match_ind,
    SQLUDF_TRAIL_ARGS)
{
    pcre *re = NULL;
    const char *error = NULL;
    int errOffset = 0;
    int rc = 0;

    // we assume successful return
    *match_ind = 0;

    // compile the pattern to its internal representation
    re = pcre_compile(pattern, 0 /* default options */, &error,
        &errOffset, NULL);
    if (re == NULL) {
        snprintf(SQLUDF_MSGTX, 70, "Regexp compilation failed at "
            "offset %d: %s\\n", errOffset, error);
        strcpy(SQLUDF_STATE, "38900");
        (*pcre_free)(re);
        return;
    }

    // match the string againts the pattern
    rc = pcre_exec(re, NULL, str->data, str->length, 0,
            0 /* default options */, NULL, 0);
    switch (rc) {
      case PCRE_ERROR_NOMATCH:
        *match = 0;
        break;
      case PCRE_ERROR_BADOPTION:
        snprintf(SQLUDF_MSGTX, 70, "An unrecognized bit was set in the "
            "options argument");
        strcpy(SQLUDF_STATE, "38901");
        break;
      case PCRE_ERROR_NOMEMORY:
        snprintf(SQLUDF_MSGTX, 70, "Not enough memory available.");
        strcpy(SQLUDF_STATE, "38902");
        break;
      default:
        if (rc < 0) {
            snprintf(SQLUDF_MSGTX, 70, "A regexp match error "
                "occured: %d", rc);
            strcpy(SQLUDF_STATE, "38903");
        }
        else {
            *match = 1;
        }
        break;
    }

    // cleanup
    (*pcre_free)(re);
    return;
}

 

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章