在Oracle中:如何判断SQL查询在不执行的情况下是否会导致更改?

在Oracle中:如何判断SQL查询在不执行的情况下是否会导致更改?,sql,oracle,sanitization,Sql,Oracle,Sanitization,我有一个包含SQL语句的字符串。我想知道查询是否会修改数据或数据库结构,或者是否只读取数据。有没有办法做到这一点 更多信息:在我们的应用程序中,我们需要让用户输入SQL查询,主要是作为应用程序报告系统的一部分。应该允许这些SQL查询从数据库中读取任何它们喜欢的内容,但不应该允许它们修改任何内容。无更新、删除、插入、表格删除、约束删除等 到目前为止,我只测试字符串中的第一个单词是否为“select”,但这太过紧凑,也太不安全 您应该只为应用程序使用的登录授予表上的select权限,以确保安全。为应

我有一个包含SQL语句的字符串。我想知道查询是否会修改数据或数据库结构,或者是否只读取数据。有没有办法做到这一点

更多信息:在我们的应用程序中,我们需要让用户输入SQL查询,主要是作为应用程序报告系统的一部分。应该允许这些SQL查询从数据库中读取任何它们喜欢的内容,但不应该允许它们修改任何内容。无更新、删除、插入、表格删除、约束删除等


到目前为止,我只测试字符串中的第一个单词是否为“select”,但这太过紧凑,也太不安全

您应该只为应用程序使用的登录授予表上的select权限,以确保安全。

为应用程序中仅具有select权限的部分创建新用户。请记住,您还需要为“只读”用户能够查看的所有表/视图创建同义词

应用程序的“常规”部分仍然可以执行其他操作(插入、更新、删除)。仅报告将使用只读用户


正如Horacio所建议的,添加“包装器”视图也是一个好主意/实践,它只公开您想要公开的内容。某种“公共API”。如果您需要更改基础表,并且不想/无法将报告更改为所述表的新定义,这可以为您提供灵活性。然而,这可能被视为大量的“额外工作”

我同意其他人的看法,正确的做法是对那些应该是只读的查询使用具有有限访问权限的单独模式


但是,另一个选项是在执行用户输入的语句之前将事务设置为只读(
set transaction read only
)。

创建视图以向最终用户公开数据,这是值得的,因为有三点:

  • 最终用户不知道数据库的真实外观
  • 您可以提供一种更简单的方法来提取某些数据片段
  • 可以创建具有只读约束的视图:
  • 创建视图项(名称、价格、税) 选择名称、价格、税率 从项目 具有只读功能;
    一些过去对我很有效,但可能不适合你的情况:

    • 使用存储过程为应用程序实现API。所有修改都是通过该API完成的。暴露于前端的程序都是完整的工作单元,这些程序负责权利的执行
    • 运行前端应用程序的用户只允许调用API存储过程和读取数据
    • 由于公开的API完成了与用户可以通过GUI执行的操作相对应的工作单元,因此让他们直接运行过程不会给他们带来任何额外的功能,也不允许他们意外损坏数据库

    SELECT*FROM table FOR UPDATE即使仅使用SELECT权限也可以工作,并且仍然会造成大量损害。如果您希望安全,只读事务会更好。

    没有人能做到这一点。应用程序需要更改数据。@Svein Bringsli:您能用其他登录名运行用户提供的查询吗?(顺便说一句,你在这里直接反驳了你自己的问题,想解释一下吗?“需要更改数据”vs“不应该被允许修改任何内容”)@Svein Bringsli-是否不可能只为执行动态报告查询而单独登录,并且按照Pratik的建议,仅以选择权限登录?我确实认为这是这里唯一一个真正万无一失的选择,并且为这个动态报告单独登录似乎是一个可以接受的折衷方案,至少对我们来说是这样me@InSane:为什么不可能?@疯狂:你可能想在那里打个问号:“不可能吗…?”-如果没有
    ,你可能在断言“不可能”。为什么我必须为表/视图创建同义词?只读用户“应该能够查看整个数据库,这会有所不同吗?如果不创建公共同义词,则只读用户必须始终使用schemaname.tablename,其中schemaname是表所属的架构。”。我想你应该读一读甲骨文。 CREATE VIEW items (name, price, tax) AS SELECT name, price, tax_rate FROM item WITH READ ONLY;