Java 确定sql查询是否修改数据库

Java 确定sql查询是否修改数据库,java,sql,sql-server,regex,Java,Sql,Sql Server,Regex,我有一个包含有效SQL表达式的字符串列表。 我只需要执行那些不修改数据库的操作。 最好的方法是什么?只是做一些类似于: if(sqlQuery.contains("DELETE")){ //don't execute this } 好像是个坏黑客 更新: 我会让这更具体。 我已经有了一个允许的SQL查询列表。我想确保只执行这些操作。 与之匹配的最佳方法是什么?DELETE并不是唯一可能修改数据库的SQL指令插入肯定会这样做,更新可能会这样做(取决于您的确切查询)。因此,仅仅分析字符串可

我有一个包含有效
SQL
表达式的字符串列表。
我只需要执行那些不修改数据库的操作。
最好的方法是什么?只是做一些类似于:

if(sqlQuery.contains("DELETE")){  
  //don't execute this
}
好像是个坏黑客

更新:
我会让这更具体。
我已经有了一个允许的
SQL
查询列表。我想确保只执行这些操作。

与之匹配的最佳方法是什么?

DELETE
并不是唯一可能修改数据库的SQL指令<代码>插入肯定会这样做,
更新
可能会这样做(取决于您的确切查询)。因此,仅仅分析字符串可能是一种困难的方法

只要性能不是真正的问题,就可以启动事务,逐个运行指令,检查每个指令受影响的行数,最后回滚事务。之后,只运行那些影响0行的语句


此外,请查看您的数据库文档:一些RDBMS E(如Oracle)不支持回滚DDL语句,如
ALTER TABLE
DROP TABLE
等…

我认为,通过简单地检查给定SQL的内容,没有一种可靠的方法可以防止记录的更改。例如,您可能有一个字段,该字段的值为“update”,而一些用户正试图查询包含该值的所有行,但SQL不会执行,因为它包含一个“黑名单”字符串。 我想唯一安全的方法是与一个用户一起执行SQL,而该用户根本无权更改记录。

最简单、最好(最全面)的方法是创建一个只读用户,并且只与该用户连接到数据库。在SQLServer中,最简单的方法是创建用户并将其添加到内置的“db_datareader”角色中。这将只允许选择

你需要担心的不仅仅是删除、插入或更新。您还必须小心调用任何存储过程,因此为了安全起见,您还需要删除执行权限、更改权限、授予权限等

编辑: 执行这个

CREATE LOGIN [user] WITH PASSWORD='password', DEFAULT_DATABASE=[your_db], CHECK_POLICY=OFF
GO
CREATE USER [user] FOR LOGIN [user]
EXEC sp_addrolemember N'db_datareader', N'your_db'
GO

您使用的是哪个RDBMS引擎?
SQL
表达式来自哪里?它们是用户生成的吗?最好的方法是创建一个新的数据库登录名,该登录名没有修改任何内容的权限,并运行该用户登录名下的所有SQL脚本。@mellamokb:是的,它们是用户生成的。@mellamokb建议,您将无法用这种方式保护数据库。只需确保所有查询都在没有权限执行这些操作的登录下执行。为什么要重新发明轮子?只需了解如何使用RDBMS中存在的用户权限系统。接受是什么意思?您的意思是要确保字符串
SELECT
位于查询的开头?这也很容易被破坏(例如:
SELECT 1;DROP TABLE ABC;
)。如果您想将SQL用户锁定为只有
选择
的权限,那么是的,应该可以。不要忘记
合并
删除表
和许多其他语句。根据具体的查询,
更新
删除
可能会使数据库保持不变(例如,如果没有与
WHERE
子句匹配的行。@Jim-将不会是只读的。@Jim:您是否正在阅读给您的答案?此答案解释了如何仅“接受”选择…@mellamokb:我的理解是,它将有效地允许
SELECT
+1这是正确的方法,通过安全性。解析SQL将一事无成!@Jim:有什么区别吗?您希望有效地允许
SELECT
的原因是为了避免恶意尝试损坏您的数据库。只要您使用字符串p纵火,你会让聪明的用户打开窗口来破坏你的数据库。但是如果你使用权限,你可以发明的每一个有效、诚实的
SELECT
查询都应该被允许,而通过
SELECT
查询潜入更新或破坏数据库的狡猾尝试将被完全阻止。@RemusRusanu I完全取消rstand创建只读用户,但存在用于解析SQL以确定其是否为只读的有效应用程序。负载平衡服务器的内容切换就是一个示例,其中所有“更新”脚本都在“读取”时发送到主数据库脚本被发送到从属服务器。有多种原因可以解释为什么需要解析SQL,而抛出“创建只读用户”的答案可能不适用。