在SQL中模拟REGEXP行为

时间:2011-01-17 10:30:27

标签: sql regex db2

我已在新dba.stackexchange.com上发布此问题(如果我必须删除一个,请告诉我。)

我正在研究DB2数据库,据我所知,不支持regexp(没有额外的库)。

所以我无法实现类似于本文“Bringing the Power of Regular Expression Matching to SQL

中所解释的内容

你知道我是否可以用SQL语句“模拟”这样的正则表达式吗?

^[aofdmep]\{1\}[a-z]\{1\}[a-z0-9]\{4\}a[sidbfkfpo]\{1\}

编辑2

https://dba.stackexchange.com/questions/651/emulate-regexp-like-behaviour-in-sql/664#664这就是我得到的答案。

  

SELECT * FROM(SELECT'afr923zs'   MyString FROM SYSIBM.SYSDUMMY1)WHERE   substr(MyString,1,1)='a'和
  substr(MyString,2,1)IN   ('a','o','f','d','m','e','p')和
  substr(MyString,3,1)BETWEEN'a'AND   'z'AND(substr(MyString,4,1)BETWEEN   'a'和'z'或   substr(MyString,4,1)BETWEEN'0'AND   '9')AND(substr(MyString,5,1)   在'a'和'z'之间   substr(MyString,5,1)BETWEEN'0'AND   '9')AND(substr(MyString,6,1)   在'a'和'z'之间   substr(MyString,6,1)BETWEEN'0'AND   '9')AND(substr(MyString,7,1)   在'a'和'z'之间   substr(MyString,7,1)BETWEEN'0'AND   '9')和substr(MyString,8,1)IN   ( 'S', 'I', 'd', 'B', 'F', 'K', 'P', 'O');

5 个答案:

答案 0 :(得分:1)

您可以使用SUBSTR完成此操作,但我建议您为此编写Java存储过程。使用免费的IBM Data Studio工具将它们放在一起非常简单。

答案 1 :(得分:1)

您可以通过xQuery在DB2中使用正则表达式:

db2 "with val as (
 select t.text
 from texts t
 where xmlcast(xmlquery('fn:matches(\$TEXT,''^[A-Za-z 0-9]*$'')') as integer) = 0
)
select * from val"

http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.xml.doc/doc/xqrfnmat.html

答案 2 :(得分:1)

关于您的EDIT 2解决方案:

SELECT *
  FROM (SELECT 'afr923zs' MyString FROM SYSIBM.SYSDUMMY1) T
 WHERE substr(MyString,1,1) = 'a'
   AND substr(MyString,2,1) IN ('a','o','f','d','m','e','p')
     AND substr(MyString,3,1) BETWEEN 'a' AND 'z'
     AND (substr(MyString,4,1) BETWEEN 'a' AND 'z' OR substr(MyString,4,1) BETWEEN '0' AND '9')
     AND (substr(MyString,5,1) BETWEEN 'a' AND 'z' OR substr(MyString,5,1) BETWEEN '0' AND '9')
     AND (substr(MyString,6,1) BETWEEN 'a' AND 'z' OR substr(MyString,6,1) BETWEEN '0' AND '9')
     AND (substr(MyString,7,1) BETWEEN 'a' AND 'z' OR substr(MyString,7,1) BETWEEN '0' AND '9')
     AND substr(MyString,8,1) IN ('s','i','d','b','f','k','p','o')
;

如果您有一长串字符,或者您有多个范围,则可以考虑使用LIKE运算符。它可以缩短和简化代码:

SELECT *
  FROM (SELECT 'afr923zs' MyString FROM SYSIBM.SYSDUMMY1) T
 WHERE substr(MyString,1,1) = 'a'
   AND 'aofdmep' like '%'||substr(MyString,2,1)||'%'
   AND substr(MyString,3,1) BETWEEN 'a' AND 'z'
   AND 'abcdefghijklmnopqrstuvwxyz0123456789' like '%'||substr(MyString,4,1)||'%'
   AND 'abcdefghijklmnopqrstuvwxyz0123456789' like '%'||substr(MyString,5,1)||'%'
   AND 'abcdefghijklmnopqrstuvwxyz0123456789' like '%'||substr(MyString,6,1)||'%'
   AND 'abcdefghijklmnopqrstuvwxyz0123456789' like '%'||substr(MyString,7,1)||'%'
   AND 'sidbfkpo' like '%'||substr(MyString,8,1)||'%'
;

对于重复的字符列表,您可以使用CROSS JOINed列常量:

SELECT *
  FROM (SELECT 'afr923zs' MyString FROM SYSIBM.SYSDUMMY1) T
  CROSS JOIN (SELECT 'abcdefghijklmnopqrstuvwxyz0123456789' alphanum FROM SYSIBM.SYSDUMMY1) T2
 WHERE substr(MyString,1,1) = 'a'
   AND 'aofdmep' like '%'||substr(MyString,2,1)||'%'
   AND substr(MyString,3,1) BETWEEN 'a' AND 'z'
   AND alphanum like '%'||substr(MyString,4,1)||'%'
   AND alphanum like '%'||substr(MyString,5,1)||'%'
   AND alphanum like '%'||substr(MyString,6,1)||'%'
   AND alphanum like '%'||substr(MyString,7,1)||'%'
   AND 'sidbfkpo' like '%'||substr(MyString,8,1)||'%'
;

您的示例不需要,但CROSS JOINed“表”可以定义多个命名的字符类列。

答案 3 :(得分:1)

现在可以在DB2 for iSeries中使用REGEXP_LIKE - 请参阅: http://www.c-sharpcorner.com/Blogs/5608/create-a-relationship-between-two-dataset-tables.aspx

答案 4 :(得分:0)

嗯,您引用的文章专门针对您的问题 - 将RegEx功能引入DB2。 DB2是IBM的产品,不是吗?如果IBM说您需要使用加载项库,那么您可能需要使用加载项库。

标准ANSI SQL,这是您可以依赖的数据库(甚至不是100%),它不支持任何远程RegEx。

Oracle提供了用于RegEx查询的外部库。 Sql Server不允许您在自己的.NET库中进行链接。如果是制造商。您的数据库正在提供有关如何使用特定外部库的信息和链接,这可能是您最好的选择。

使用标准SQL语句,您可以做的唯一匹配是简单的通配符匹配。

无论如何,掌握可扩展性都符合您的最佳利益,因为一旦您知道如何执行此操作,您就可以疯狂地扩展数据库的功能,以执行您可能想要的几乎任何类型的查询。