有没有办法检查某个记录是否会被某个select语句选中,然后再将其插入数据库?

时间:2013-09-23 13:02:22

标签: sql oracle

在我们的应用程序中,我们需要阻止用户将记录插入不符合条件的数据库。条件是select语句的where子句,由一些管理员用户定义。这是一个例子,有一个名为'Book'的表,管理员用户已经将标准定义为“pages< = 200 OR type ='Children's book'”。根据定义的标准,不允许将页数超过200且类型不是“儿童书”的书籍插入数据库。

Table: Book (id, name, author, pages, type)

Criteria: "pages<=200 OR type='Children's book'"

标准可能更复杂但遵循oracle sql语法。我能想到的一个选择是首先插入记录,然后检查是否可以按标准选择,如果没有,那么我们从数据库中删除,但我认为应该有一个更简洁的方法来完成这项工作。如果可以通过单个sql语句完成它将会很棒。

有没有人有更好的方法来完成这项工作?任何答案都将不胜感激。

更新

感谢您的回答,我想我应该提供更多细节。

有问题的用户是应用程序用户,包括“管理员用户”,它不是dba。标准可以经常更改,并且我们可能在不同用户组的同一个表上有不同的标准。所以希望,检查可以在应用程序端完成。我们正在使用具有自己的ORM的django,但我想我应该首先找到一种方法来使用sql语句,这将在某些时候连接标准。理想情况下,我们可以将'where子句'约束附加到insert语句,以便在值满足这些约束时将其记录到数据库中,否则不执行任何操作。

3 个答案:

答案 0 :(得分:1)

如果标准与您的示例相同,则应添加一些check constraints

Alter table book add CONSTRAINT check_type CHECK (type = 'Children''s book');
Alter table book add CONSTRAINT check_pages CHECK (pages >=200);

答案 1 :(得分:1)

这样做的一个非常好的方法是使用视图“with check option”(可能还有sys_context)。

例如,

CREATE OR REPLACE VIEW test (id, col_1) AS
SELECT id,  col_1 
  FROM some_table
 WHERE col1  = SYS_CONTEXT ('CTX', 'XYZ')
  WITH CHECK OPTION;

然后为视图授予插入权限并撤消对表的插入权限。让用户插入视图。

“with check option”确保插入到视图中的所有行都传递“where子句”。

这也是处理Oracle标准版中行级安全性(如虚拟专用数据库)的好方法。

您可以创建2个oracle模式,一个拥有表和视图的模式,以及一个将从视图中选择/插入/删除的模式(并且无权对表执行任何操作)。

当用户登录时设置sys_context并且bam ....你有完美的行级安全性。

答案 2 :(得分:0)

如果您拥有Enterprise Edition,另一种处理此问题的方法是设置Oracle虚拟专用数据库: http://www.oracle.com/technetwork/database/security/index-088277.html