【问题标题】:Restrict input of PK if generated by sequencing and triggers in oracle 11g xe如果在 oracle 11g xe 中由排序和触发器生成,则限制 PK 的输入
【发布时间】:2014-07-07 00:21:12
【问题描述】:

我知道如果使用排序,我们可以在应用程序逻辑中限制对 PK 的插入操作。如果您在应用程序之外插入,是否有任何方法可以限制插入,例如来自 SQL developer 或 SQL plus。如果有,请详细说明,因为我是新手。

如果很明显,请原谅我

问候

【问题讨论】:

  • 不是很清楚你想要达到什么。是否要防止用户在某些 SQL 工具(例如 SQL/Plus)中执行INSERT 时直接设置 PK? (顺便说一句,在谈到 RDBMS 系统时,querying 这个词通常只用于SELECT 语句)
  • @frank Schmitt 抱歉含糊其辞。我会编辑这个问题,是的,你是对的,我想在按顺序生成 PK 时限制插入操作。

标签: database triggers oracle11g primary-key


【解决方案1】:

您的触发器可能只是忽略任何用户提供的主要值,如果它只是从序列中设置 PK 列而不检查:

begin
  :new.pk_column := seq.nextval;
end;

您有时会看到提供的值优先于以下内容:

begin
  if :new.pk_column is null then
    :new.pk_column := seq.nextval;
  end if;
end;

... 这给了您灵活性,但无法控制;所以有人可以手动输入一个高键值,当序列达到相同的值时,你会得到一个键冲突 ORA-01001 唯一索引冲突,这并不理想。从您的评论看来,您目前可能遇到这种情况。

如果您想让它更明显并真正阻止用户尝试设置主键,而不是默默地忽略(或接受)他们提供的任何值,您可以检查键列是否为被设置为触发器的一部分,如果是,则抛出异常:

create or replace trigger ...
...
begin
  if :new.pk_column is not null then
    raise_application_error(-20001, 'Do not set a value for primary key');
  end if;
  :new.pk_column := seq.nextval;
  ...
end;
/

SQL Fiddle demo.

在大量加载包含键的数据期间,您需要禁用或修改触发器,例如从之前的导出中导入。

您还可以通过创建一个包含所有其他列的表视图来完全隐藏主键列,然后使用一个仍然从序列生成主键的代替触发器。但是主键可能需要是可见的,至少如果他们想用它作为外键来查找相关记录的话。

【讨论】:

  • 我默认使用了SQL developer自带的触发器,我想,可能是我搞错了,当我执行插入操作时,它没有忽略用户输入的值。可能是我做错了其他事情
  • @chaudry - 不确定你指的是哪个默认值。如果您将原始触发器语句添加到问题中会更清楚。但它可能一直选择接受传递的值 - 有时人们希望它以这种方式工作,但它往往会在某些时候导致键冲突的问题,所以我认为你很好不要那样离开它。
  • 我可以使用您提供的触发器吗?
  • @chaudry - 你应该修改你现有的触发器来做同样的检查;它可能正在设置或验证其他东西,因此盲目地替换它可能会导致问题。这将防止手动提供值,并在有人尝试时停止插入。
猜你喜欢
  • 1970-01-01
  • 2017-07-19
  • 2016-03-29
  • 2018-04-15
  • 2018-01-30
  • 1970-01-01
  • 2021-07-12
  • 2021-10-18
  • 2016-06-24
相关资源
最近更新 更多