正则表达式:SQL语句是否包含WHERE子句?

问题描述:

我需要一个正则表达式来确定给定的SQL语句是否有WHERE子句。我的问题是,传递的SQL语句很可能很复杂,所以我不能仅仅依赖WHERE语句的存在。正则表达式:SQL语句是否包含WHERE子句?

例如,这应与

SELECT Contacts.ID 
    , CASE WHEN (Contacts.Firstname IS NULL) THEN '' 
      ELSE CAST(Contacts.Firstname AS varchar) 
     END AS Firstname 
    , CASE WHEN (Contacts.Lastname IS NULL) THEN '' 
      ELSE CAST(Contacts.Lastname AS varchar) 
     END AS Lastname 
    , CASE WHEN (tbl_ContactExtras.Prequalified=-1 OR 
        tbl_ContactExtras.Prequalified IS NULL) THEN '' 
      WHEN tbl_ContactExtras.Prequalified=0 THEN 'No' 
      WHEN tbl_ContactExtras.Prequalified=1 THEN 'Yes - Other' 
      WHEN tbl_ContactExtras.Prequalified=2 THEN 'Yes' 
      ELSE CAST(tbl_ContactExtras.Prequalified AS varchar) 
     END AS Prequalified 
FROM contacts 
LEFT JOIN tbl_ContactExtras 
ON tbl_ContactExtras.ContactID = Contacts.ID 
WHERE (Contacts.Firstname LIKE 'Bob%') 

,这不应该匹配:

SELECT Contacts.ID 
    , CASE WHEN (Contacts.Firstname IS NULL) THEN '' 
      ELSE CAST(Contacts.Firstname AS varchar) 
     END AS Firstname 
    , CASE WHEN (Contacts.Lastname IS NULL) THEN '' 
      ELSE CAST(Contacts.Lastname AS varchar) 
     END AS Lastname 
    , CASE WHEN (tbl_ContactExtras.Prequalified=-1 OR 
        tbl_ContactExtras.Prequalified IS NULL) THEN '' 
      WHEN tbl_ContactExtras.Prequalified=0 THEN 'No' 
      WHEN tbl_ContactExtras.Prequalified=1 THEN 'Yes - Other' 
      WHEN tbl_ContactExtras.Prequalified=2 THEN 'Yes' 
      ELSE CAST(tbl_ContactExtras.Prequalified AS varchar) 
     END AS Prequalified 
FROM contacts 
LEFT JOIN tbl_ContactExtras 
ON tbl_ContactExtras.ContactID = Contacts.ID 

这些都是一些简单的语句的例子:一个声明可能在它长达30点CASE声明,或者根本没有。

我需要以编程方式添加WHERE参数,但正确执行此操作需要知道WHERE子句是否已存在。

在正则表达式上的任何想法,将为此工作?如果没有,关于如何区分两者的其他想法?

谢谢,

这是不可能的,因为WHERE子句可以任意嵌套在FROM子句中。

+1

“正则表达式无法解析”。 – 2010-09-15 02:06:44

+0

我不想通过解析器,但我不得不去。谢谢。 – Justin808 2010-09-15 02:23:08

所有的连接都一样吗?如果是这样,你可以找到全部或部分FROM语句的索引(也许使用正则表达式来容忍语法和空白的细微差别),然后查找该索引之后WHERE的出现。

一般来说,使用解析器会更好。但是如果这只是一次性的事情而且陈述都非常相似,那么上述方法应该没问题。

正则表达式不是为了这样做而设计的。正确解析SQL需要匹配平衡圆括号(以及其他匹配的对,如引号),正则表达式是而不是旨在执行的操作(纯正规表达式甚至没有配备; PCRE可以但不是很漂亮)。

相反,只需编写一个基本的状态机或其他东西来解析它。

+0

转义引号可以通过正则表达式匹配。不过,除此之外,你是对的。 – SLaks 2010-09-15 01:55:02

这可能赶不上所有箱子但你会发现,你可以只是找到最后一个from,并在声明的最后where赶上了一大半。

如果wherefrom之后,则它有where子句。如果wherefrom之前(或根本没有where),则不存在where子句。

有时候,只要它们有适当的文档记录,在代码中保留限制或限制即可,

例如,我在一个项目的工作是解析SQL之前,我们发现它没有处理之类的东西between

where recdate between '2010-01-01' and '2010-12-31' 

与其花的钱一斗载荷解决问题(也可能引入的方式漏洞),我们只是公布它作为一个限制,并告诉大家,他们不得不将其改为:

where recdate >= '2010-01-01' 
    and recdate <= '2010-12-31' 

问题解决了。虽然这是很好的让客户满意,你不必去迎合心血来潮:-)

除此之外,你需要一个SQL语法分析程序和SQL是一个漂亮的语言来解析,信任我在那一个。

你试图解决什么问题?您是否试图确定向这些现有查询添加约束是否安全?

例如,如果你已经有了这个查询

... 
where foo = 'bar' 

,那么你知道它的安全添加

and bat = 'quux' 

,但如果你没有一个WHERE子句不已,那么你有做它

where bat = 'quux' 

这是你想解决的问题?如果是这样,你可以通过为那些没有的查询添加一个“WHERE 0 = 0”来让你使用的每个SQL查询都有一个WHERE子句吗?然后你知道你的后处理阶段每个查询已经有一个。

这当然只是猜测。你的问题听起来可能是更大的问题。