开发者

Emulate REGEXP like behaviour in SQL

I've posted this question on the new dba.stackexchange.com (please, let me know if I have to delete one).

I'm working on a DB2 database, and as far as I can see regexp is not supported (without additional libraries).

So I cannot implement something similar to what is explained in this article "Bringing the Power of Regular Expression Matching to SQL"

Do you know if I can "emulate", with a SQL statement, a regular expression like this?

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

EDIT 2

https://dba.stackexchange.com/questions/651/emulate-regexp-like-behaviour-in-sql/664#664 this is the answer I've got.

SELECT * FROM (SELECT 'afr923zs' MyString FROM SYSIBM.SYSDUMMY1) WHERE substr(MyString,1,1) = 'a' AND

substr(MyString,2,1) IN ('a','o','f','d','m',开发者_如何学Go'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');


Regarding your EDIT 2 solution:

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')
;

You might consider using the LIKE operator when you have a long list of characters, or if you have multiple ranges. It can shorten and simplify the code:

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)||'%'
;

For repeated character lists you could use a CROSS JOINed column constant:

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)||'%'
;

Not needed for your example, but the CROSS JOINed "table" could define multiple named character class columns.


You could accomplish this using SUBSTR, but I would recommend writing a Java stored procedure for this. It's fairly simple to put one together using the free IBM Data Studio tool.


You can use Regular Expression in DB2 via xQuery:

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


REGEXP_LIKE is now available in DB2 for iSeries - see: http://www.itjungle.com/fhg/fhg051915-story01.html


Well, the article you referenced is specifically addressing your question - bringing RegEx power to DB2. DB2 is IBM's product, no? If IBM says you need to use an add-in library then chances are you need to use an add-in library.

Standard ANSI SQL, which is all you can count on for sure (and even that not 100%) from a database, does not support anything remotely RegEx.

Oracle provides external libraries to use for RegEx querying. Sql Server does not but allows you to link in your own .NET libraries. If the mfg. of your db is providing information and links on how to use a specific external library, that is probably your best bet to follow.

With a standard SQL statement, the only matching you can do is simple wildcard matching.

Getting a handle on extensibility would be in your best interest anyway, as once you know how to do this, you can wildly extend the functionality of your database to do almost any kind of querying you could possibly want.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜