我需要一个正则表达式来确定给定的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
语句,或者根本没有。{/ p>
我需要以编程方式添加WHERE
个参数,但正确执行此操作需要知道是否已存在WHERE
子句。
关于正则表达式的任何想法都适用于此?如果不是,关于如何区分两者的任何其他想法?
谢谢,
答案 0 :(得分:2)
这是不可能的,因为WHERE
子句可以任意嵌套在FROM
子句中。
答案 1 :(得分:1)
这可能无法捕获所有个案,但您可能会发现只能通过查找语句中的最后一个from
和最后一个where
来捕获大部分。
如果where
位于from
之后,则它具有where
子句。如果where
位于from
之前(或根本没有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 不是一种可以解析的漂亮语言,请相信我。
答案 2 :(得分:0)
所有连接都是一样的吗?如果是这样,你可以找到全部或部分FROM语句的索引(可能使用正则表达式来容忍语法和空格中的细微差别),然后在该索引之后查找单词WHERE的出现。
一般来说,最好使用解析器。但如果这只是一次性的事情,并且陈述都非常相似,那么上述方法应该没问题。
答案 3 :(得分:0)
正则表达式不是为此而设计的。正确解析SQL需要匹配平衡括号(以及其他匹配对,例如引号),正则表达式不设计用来做(并且纯正的正则表达式甚至没有配备; PCRE可以,但它不漂亮)
相反,只需编写一个基本状态机或其他东西来解析它。
答案 4 :(得分:0)
你想解决的问题是什么?您是否尝试确定向这些现有查询添加约束是否安全?
例如,如果您有此查询
...
where foo = 'bar'
然后你知道添加
是安全的and bat = 'quux'
但是如果你还没有WHERE子句,那么你必须以
的方式进行where bat = 'quux'
这是你要解决的问题吗?如果是这样,您是否可以通过向那些没有查询的查询添加“WHERE 0 = 0”来使您正在使用的每个SQL查询都有WHERE子句?然后,您知道在后处理阶段,每个查询都有一个。
当然,这只是猜测。你的问题听起来可能是更大的问题。