科技行者

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

知识库

知识库 安全导航

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

DB2中如何实现正则表达式

  • 扫一扫
    分享文章到微信

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

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

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

关键字: IBM 数据库 DB2

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

清单 7. regex2 的 C UDF 入口点


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

// data structure mapped on the scratchpad for easier use and access
// to the objects
// the size of the scratchpad defined in the CREATE FUNCTION statement
// must be at least as large as sizeof(scratchPadMapping)
struct scratchPadMapping {
    pcre *re;
    pcre_extra *extra;
    const char *error;
    int errOffset;
};

void regexpPerf(
    // 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_ALL) // SQLUDF_SCRAT & SQLUDF_CALLT
{
    int rc = 0;
    struct scratchPadMapping *scratch = NULL;

    // map the buffer of the scratchpad and assume successful return
    scratch = (struct scratchPadMapping *)SQLUDF_SCRAT->data;
    *match_ind = 0;

    switch (SQLUDF_CALLT) {
      case SQLUDF_FIRST_CALL:
        // initialize data on the scratchpad
        scratch->re = NULL;
        scratch->extra = NULL;
        scratch->error = NULL;
        scratch->errOffset = 0;

        // compile the pattern (only in the FIRST call
        scratch->re = pcre_compile(pattern, 0 /* default options */,
            &scratch->error, &scratch->errOffset, NULL);
        if (scratch->re == NULL) {
            snprintf(SQLUDF_MSGTX, 70, "Regexp compilation failed at "
                "offset %d: %s\\n", scratch->errOffset, scratch->error);
            strcpy(SQLUDF_STATE, "38900");
            rc = -1;
            break;
        }

        // further analyze the pattern (might return NULL)
        scratch->extra = pcre_study(scratch->re,
            0 /* default options */, &scratch->error);

        /* fall through to NORMAL call because DB2 expects a result
           already in the FIRST call */

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

      // cleanup in FINAL call, or if we encountered an error in
      // the FIRST call (DB2 will make a FINAL call if we encounter
      // an error in any NORMAL call)
      if (SQLUDF_CALLT == SQLUDF_FINAL_CALL ||
          (SQLUDF_CALLT == SQLUDF_FIRST_CALL && rc < 0)) {
          (*pcre_free)(scratch->re);
          (*pcre_free)(scratch->extra);
      }
      return;
}

 

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

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

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