正则表达式匹配常见的SQL语法?
上周,我在编写一些单元测试,以生成一段生成SQL语句的代码。
我试图找出一个与SELECT,INSERT和UPDATE语法匹配的正则表达式,以便可以验证我的方法正在生成有效的SQL,并且在经过3-4小时的搜索并弄乱了各种正则表达式编辑器后,我放弃了。
我设法获得了部分匹配,但是由于引号中的某个部分可以包含任何字符,因此它会快速扩展以匹配整个语句。
任何帮助将不胜感激,我对正则表达式不是很好,但我想了解更多有关正则表达式的信息。
顺便说一句,我追求的是Cregex。
澄清度
我不想访问数据库,因为这是单元测试的一部分,并且我不需要维护数据库来测试我的代码。这可能比该项目的寿命更长。
解决方案
我们是否尝试过惰性选择器。他们没有尽可能地匹配,而是尽可能地少匹配,这可能是我们需要的报价。
我假设我们做了类似"。*"的尝试,而尝试使用[[^"] *"来防止我们吃掉整行。它仍然会在字符串中包含"的情况下给出误报。
让我烦恼的是:我们是否可以将生成的SQL传递给数据库并在数据库上使用EXPLAIN并捕获任何表明格式错误的SQL的异常?
要验证查询,只需在SET NOEXEC ON上运行它们,这就是Entreprise Manager在解析查询而不执行查询时执行的方式。
此外,如果我们使用正则表达式来验证sql查询,则几乎可以肯定会遗漏一些极端情况,或者由于其他原因该查询无效,即使它在语法上是正确的。
我建议创建一个具有相同架构的数据库(可能使用嵌入式SQL引擎),并将该SQL传递给该数据库。
正则表达式只能与有限状态自动机可以解析的语言匹配,这是非常有限的,而SQL是一种语法。可以证明我们无法使用正则表达式验证SQL。因此,我们可以停止尝试。
我认为我们甚至不需要创建架构即可验证该语句,因为在成功解析该语句之前,系统不会尝试解析object_name等。
以Oracle为例,如果这样做,肯定会出现错误:
select * from non_existant_table;
在这种情况下," ORA-00942:表或者视图不存在"。
但是,如果执行:
select * frm non_existant_table;
然后,我们将收到语法错误," ORA-00923:在期望的位置找不到FROM关键字"。
应该有可能将错误分类为语法分析错误,这些语法分析错误指示语法不正确以及与表名称和权限等有关的错误。
另外,不同的RDBMS甚至不同版本允许使用不同语法的问题,我认为我们确实必须使用db引擎来完成此任务。
据我所知,这超出了正则表达式的范围,并且我们接近BnF和编译器的黑手党。
http://savage.net.au/SQL/
想要进行正确的语法高亮显示的人也会遇到同样的事情。我们开始将东西塞入正则表达式中,然后最终编写了一个编译器...
SQL是2类语法,它功能强大,无法用正则表达式描述。就像我们决定先生成Ccode然后在不调用编译器的情况下对其进行验证一样。通常,数据库引擎太复杂而无法轻易地进行存根。
也就是说,我们可以尝试ANTLR的SQL语法。
有ANTLR语法可以解析SQL。使用内存数据库或者非常轻量的数据库(例如sqlite)确实是一个更好的主意。从解析的角度来看,测试SQL是否有效对我来说似乎很浪费,而对于检查表和列名称以及查询的细节而言,这很有用。