【问题标题】:Constraining column values using trigger [duplicate]使用触发器约束列值
【发布时间】:2015-05-07 23:59:16
【问题描述】:

我正在尝试使用 trigger(正如 Bohemian 建议的 here)来限制我的表中将出现多少 yes/no。我希望isTeamLead 列中的每个唯一项在project 列中最多有一个yes,但可以根据需要拥有尽可能多的no。对于no,似乎我能做的最好的事情是使用一种解决方法,我可以使用no1no2no3 等。我的代码成功插入了yes 行,但在no 行。

DROP TABLE team CASCADE CONSTRAINTS PURGE ;
create table team (
  name varchar2(10) NOT NULL UNIQUE,
  project varchar2(10),
  isTeamLead char(10) check (isTeamLead IN ('No', 'Yes'))
);

create unique index only_one_yes_per_project on team(project, isTeamLead);

DROP SEQUENCE test1_seq; 
create SEQUENCE test1_seq
START WITH 1
INCREMENT BY 1;

set define off;
set serveroutput on format wrapped;
CREATE OR REPLACE TRIGGER insert_yesno
  BEFORE INSERT ON team
  FOR EACH ROW
BEGIN
  IF (:new.isTeamLead = 'No') THEN 
    DBMS_OUTPUT.put_line(:new.isTeamLead);
    :new.isTeamLead := CONCAT('No', test1_seq.nextval);
    DBMS_OUTPUT.put_line(:new.isTeamLead);
    INSERT INTO team VALUES
      (:new.name, :new.project, :new.isTeamLead);
  END IF; 
END insert_yesno;
/

insert into team values ('member1', 'project1', 'Yes');
insert into team values ('member2', 'project1', 'No');
insert into team values ('member3', 'project1', 'No');
insert into team values ('member4', 'project2', 'No');
insert into team values ('member5', 'project2', 'Yes');
insert into team values ('member6', 'project2', 'No');

select * from team;

这是错误报告的快照:

Error starting at line : 244 in command -
insert into team values ('member6', 'project2', 'No')
Error report -
SQL Error: ORA-02290: check constraint (SEDEH.SYS_C0012563) violated
ORA-06512: at "SEDEH.INSERT_YESNO", line 6
ORA-04088: error during execution of trigger 'SEDEH.INSERT_YESNO'
02290. 00000 -  "check constraint (%s.%s) violated"
*Cause:    The values being inserted do not satisfy the named check

如果有任何想法,请告诉我。谢谢。

运行 Oracle Database 11g Enterprise Edition Release 11.2.0.1.0

【问题讨论】:

  • 检查约束允许哪些值?您正在尝试插入“否” - 如果检查约束设置为允许“是”和“否”,那么它将不允许“否”。
  • 你能发布一个重现问题的测试用例吗?您说您正在使用触发器,但您的示例中没有任何内容显示正在使用触发器。检查约束失败,但我们不知道该约束是如何定义的。
  • @JustinCave 我刚刚修改并包含了指向code 的链接。我以为我已经包含了它。刚刚注意到,如果我删除if/else 逻辑并使用WHEN (:new.isTeamLead = 'No'),我得到no 行中的2 个。有趣。
  • 您的check 约束没有意义——您不能同时将isTeamLead 约束为YesNo,然后尝试将值No12345 插入列。您的触发器还应该修改:new 伪记录,而不是尝试将insert 数据放入team 表中(如果它有效,将创建一个无限循环)。但看起来你真的想要一个基于函数的索引。
  • @JustinCave 哎呀,应该说像check (isTeamLead = 'Yes' or isTeamLead like 'No%') 这样的话。也是无限循环的好点。

标签: sql oracle oracle11g triggers


【解决方案1】:

为什么不添加一个唯一的基于函数的索引?以下内容应将列限制为每个项目只有一名团队负责人:

create unique index idx_team_isTeamLead_yes on
    team(case when isTeamLead = 'yes' then project else NULL end);

这利用了 Oracle 忽略所有索引列都是 NULL 的行。

【讨论】:

  • 太棒了!我在修改后的code 上得到SQL Error: ORA-00942: table or view does not exist,但一切都很好。只是好奇你是否遇到了同样的错误。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多