如何区分修改数据的SQL语句和只读的语句?

问题描述:

我需要编写一个jdbc兼容的驱动程序包装器,其目的是记录所有修改数据的SQL语句。区分那些修改数据的语句和那些只读取数据的语句最简单的方法是什么?我想唯一的方法是即时解析SQL代码,任何可以做到这一点的库?如何区分修改数据的SQL语句和只读的语句?

+0

如果语句是对存储过程的调用会怎么样? – Quassnoi 2010-09-14 14:07:29

+0

如果SP,我会认为它默认修改数据。为了更详细的解决方案,我可能会实现一个只读(或修改列表)SP的列表。 – Dan 2010-09-14 15:05:02

你或许可以找到一些完整的SQL解析器,例如one,但是如果你的包装只会拦截单个语句,那么你可能(没有足够的细节)将SELECT语句视为只读,而其他所有内容都视为修改数据的语句。

+0

“许多人试图用解析器生成工具编写完整的SQL语法并失败。”他们说。似乎比我最初想象的更复杂.. – Dan 2010-09-15 01:56:31

+0

@丹,是的,特别是由于标准的扩展。例如,你可以在这里找到SQL语法http://savage.net.au/SQL/,它在BNF中可以找到解析器并做很好的事情;然而,如果你的目标是完全符合,那么你很可能谈论完全符合一些现有的RDBMS(甚至更糟糕的是,多个RDBMS),并且有更多的版本,并且更多没有记录:) – Unreason 2010-09-15 16:06:09

我认为一个很好的开始是寻找以INSERT,UPDATE或DELETE开头的查询。确保在测试字符串之前修剪前导空格。

如果要包含模式更改语句,请包括诸如CREATE,ALTER,DROP和TRUNCATE之类的命令。

上述方法的具体情况将取决于您使用的数据库。例如,在一个字符串中可能有批处理命令,用分号分隔。您将需要解析字符串以查找这样的实例。

+0

不要忘了现代SQL DBMS上的MERGE。 – 2010-09-14 13:53:47

+2

在某些RDBMS系统中,您可以修改不与插入,更新或删除操作相关的语句。 (例如,在SQL Server中,其中的任何一个都可以嵌入到cte中,因此首先使用“WITH”语句。)这是一个复杂的问题,并且为您的系统找到第三方工具可能是最安全的选择。 – 2010-09-14 13:55:45

如果这不是一般用途的包装,我只会记录每个呼叫executeXXX()方法,除了调用executeQuery(),然后在客户端代码中调用appropiate方法。

如果您希望它是通用目的并希望避免解析SQL,您可以调查getUpdateCount()方法以及executeXXX()方法的返回值。这意味着在执行之后记录,并且我认为它不会100%正确。