问题描述
嗨,问-汤姆-团队,
我有一个独特的约束违反的问题,我不明白。
我有一个表格,可以将问题存储到问卷的项目中。这些问题在特定的年份范围内有效:
我已经编写了一个过程来插入数据,并在更新条目时自动更改to_dat。
为了只允许一个给定的变量和一个给定的时间段与类似的问题,我实现了一个唯一的约束四列:
长话短说,我在插入数据时遇到问题。使用该过程,以下操作正常,并插入行:
当尝试插入以下行时,由于唯一-约束-如预期的那样发生错误:
所以我把问题 (第二个参数) 改为 'E',并试图插入它。那是当唯一约束违反发生时,我不明白。
也许我错过了一些明显的东西。
谢谢你的帮助。
我有一个独特的约束违反的问题,我不明白。
我有一个表格,可以将问题存储到问卷的项目中。这些问题在特定的年份范围内有效:
CREATE TABLE question ( id NUMBER CONSTRAINT nnc_quest_id NOT NULL, variable_id VARCHAR2(7) CONSTRAINT nnc_quest_variable_id NOT NULL, question VARCHAR2(255) CONSTRAINT nnc_quest_question NOT NULL, from_year SMALLINT CONSTRAINT nnc_quest_from_year NOT NULL, to_year SMALLINT, creat_id NUMBER CONSTRAINT nnc_quest_creat_id NOT NULL, creat_dat TIMESTAMP WITH LOCAL TIME ZONE DEFAULT systimestamp CONSTRAINT nnc_quest_creat_dat NOT NULL, act_id NUMBER, act_dat TIMESTAMP WITH LOCAL TIME ZONE DEFAULT NULL ); CREATE UNIQUE INDEX idx_quest_id ON question ( id ASC ); ALTER TABLE question ADD CONSTRAINT pk_quest PRIMARY KEY ( id ); CREATE SEQUENCE quest_id_seq START WITH 1 NOCACHE ORDER; CREATE OR REPLACE TRIGGER quest_id_trg BEFORE INSERT ON question FOR EACH ROW WHEN ( new.id IS NULL ) BEGIN :new.id := quest_id_seq.nextval; END; /
我已经编写了一个过程来插入数据,并在更新条目时自动更改to_dat。
create or replace PROCEDURE INSERT_QUESTION_PROC ( IN_VARIABLE_ID IN VARCHAR2 , IN_QUESTION IN QUESTION.QUESTION%TYPE , IN_FROM_YEAR IN QUESTION.FROM_YEAR%TYPE , IN_TO_YEAR IN QUESTION.TO_YEAR%TYPE , IN_CREAT_ID IN QUESTION.CREAT_ID%TYPE , IN_CREAT_DAT IN QUESTION.CREAT_DAT%TYPE DEFAULT SYSTIMESTAMP ) AS BEGIN UPDATE question SET to_year = CASE WHEN (in_from_year > from_year) THEN in_from_year - 1 ELSE in_from_year END , act_id = in_creat_id, act_dat = in_creat_dat WHERE variable_id = in_variable_id and to_year IS NULL; INSERT INTO question (variable_id, question, from_year, to_year, creat_id) VALUES (in_variable_id, in_question, in_from_year, in_to_year, in_creat_id); END INSERT_QUESTION_PROC;
为了只允许一个给定的变量和一个给定的时间段与类似的问题,我实现了一个唯一的约束四列:
ALTER TABLE question ADD CONSTRAINT um_quest UNIQUE ( variable_id, question, from_year, to_year ); CREATE UNIQUE INDEX idx_quest_variable_id_question_from_year_to_year ON question ( variable_id ASC, question ASC, from_year ASC, to_year ASC );
长话短说,我在插入数据时遇到问题。使用该过程,以下操作正常,并插入行:
BEGIN INSERT_QUESTION_PROC('f1','A',2001,NULL,1); INSERT_QUESTION_PROC('f1','B',2001,NULL,1); INSERT_QUESTION_PROC('f1','C',2001,NULL,1); INSERT_QUESTION_PROC('f1','D',2001,NULL,1); INSERT_QUESTION_PROC('f1','D',2001,NULL,1); END;
当尝试插入以下行时,由于唯一-约束-如预期的那样发生错误:
BEGIN INSERT_QUESTION_PROC('f1','D',2001,NULL,1); END;
所以我把问题 (第二个参数) 改为 'E',并试图插入它。那是当唯一约束违反发生时,我不明白。
BEGIN INSERT_QUESTION_PROC('f1','E',2001,NULL,1); END;
也许我错过了一些明显的东西。
谢谢你的帮助。
专家解答
这是你的更新...它试图在不引用 “问题” 值的情况下设置值
我添加了一些调试,以便您可以看到它的发生
我添加了一些调试,以便您可以看到它的发生
SQL> SQL> SQL> CREATE TABLE question ( 2 id NUMBER 3 CONSTRAINT nnc_quest_id NOT NULL, 4 variable_id VARCHAR2(7) 5 CONSTRAINT nnc_quest_variable_id NOT NULL, 6 question VARCHAR2(255) 7 CONSTRAINT nnc_quest_question NOT NULL, 8 from_year SMALLINT 9 CONSTRAINT nnc_quest_from_year NOT NULL, 10 to_year SMALLINT, 11 creat_id NUMBER 12 CONSTRAINT nnc_quest_creat_id NOT NULL, 13 creat_dat TIMESTAMP WITH LOCAL TIME ZONE DEFAULT systimestamp 14 CONSTRAINT nnc_quest_creat_dat NOT NULL, 15 act_id NUMBER, 16 act_dat TIMESTAMP WITH LOCAL TIME ZONE DEFAULT NULL 17 ); Table created. SQL> CREATE UNIQUE INDEX idx_quest_id ON 2 question ( 3 id ASC 4 ); Index created. SQL> ALTER TABLE question ADD CONSTRAINT pk_quest PRIMARY KEY ( id ); Table altered. SQL> SQL> CREATE SEQUENCE quest_id_seq START WITH 1 NOCACHE ORDER; Sequence created. SQL> SQL> CREATE OR REPLACE TRIGGER quest_id_trg BEFORE 2 INSERT ON question 3 FOR EACH ROW 4 WHEN ( new.id IS NULL ) 5 BEGIN 6 :new.id := quest_id_seq.nextval; 7 END; 8 / Trigger created. SQL> SQL> create or replace procedure PPP(m varchar2, s int) is 2 begin 3 dbms_output.put_line(m||':'||s); 4 5 for i in ( select * from question ) 6 loop 7 dbms_output.put_line(i.variable_id||','||i.question||','||i.from_year||','||nvl(i.to_year,-1)); 8 end loop; 9 dbms_output.put_line('----------------'); 10 end; 11 / Procedure created. SQL> SQL> SQL> create or replace PROCEDURE INSERT_QUESTION_PROC 2 ( 3 IN_VARIABLE_ID IN VARCHAR2 4 , IN_QUESTION IN QUESTION.QUESTION%TYPE 5 , IN_FROM_YEAR IN QUESTION.FROM_YEAR%TYPE 6 , IN_TO_YEAR IN QUESTION.TO_YEAR%TYPE 7 , IN_CREAT_ID IN QUESTION.CREAT_ID%TYPE 8 , IN_CREAT_DAT IN QUESTION.CREAT_DAT%TYPE DEFAULT SYSTIMESTAMP 9 ) AS 10 BEGIN 11 dbms_output.put_line('about to update'); 12 UPDATE question 13 SET to_year = CASE 14 WHEN (in_from_year > from_year) THEN in_from_year - 1 15 ELSE in_from_year 16 END 17 , act_id = in_creat_id, act_dat = in_creat_dat 18 WHERE variable_id = in_variable_id 19 and to_year IS NULL; 20 ppp ('after update ',sql%rowcount); 21 INSERT INTO question 22 (variable_id, question, from_year, to_year, creat_id) 23 VALUES (in_variable_id, in_question, in_from_year, in_to_year, in_creat_id); 24 25 ppp ('after insert',null); 26 27 END INSERT_QUESTION_PROC; 28 / Procedure created. SQL> SQL> SQL> ALTER TABLE question 2 ADD CONSTRAINT um_quest UNIQUE ( variable_id, 3 question, 4 from_year, 5 to_year ); Table altered. SQL> SQL> set serverout on SQL> BEGIN 2 INSERT_QUESTION_PROC('f1','A',2001,NULL,1); 3 INSERT_QUESTION_PROC('f1','B',2001,NULL,1); 4 INSERT_QUESTION_PROC('f1','C',2001,NULL,1); 5 INSERT_QUESTION_PROC('f1','D',2001,NULL,1); 6 INSERT_QUESTION_PROC('f1','D',2001,NULL,1); 7 END; 8 / about to update after update :0 ---------------- after insert: f1,A,2001,-1 ---------------- about to update after update :1 f1,A,2001,2001 ---------------- after insert: f1,A,2001,2001 f1,B,2001,-1 ---------------- about to update after update :1 f1,A,2001,2001 f1,B,2001,2001 ---------------- after insert: f1,A,2001,2001 f1,B,2001,2001 f1,C,2001,-1 ---------------- about to update after update :1 f1,A,2001,2001 f1,B,2001,2001 f1,C,2001,2001 ---------------- after insert: f1,A,2001,2001 f1,B,2001,2001 f1,C,2001,2001 f1,D,2001,-1 ---------------- about to update after update :1 f1,A,2001,2001 f1,B,2001,2001 f1,C,2001,2001 f1,D,2001,2001 ---------------- after insert: f1,A,2001,2001 f1,B,2001,2001 f1,C,2001,2001 f1,D,2001,2001 f1,D,2001,-1 ---------------- PL/SQL procedure successfully completed. SQL> SQL> BEGIN 2 INSERT_QUESTION_PROC('f1','D',2001,NULL,1); 3 END; 4 / about to update BEGIN * ERROR at line 1: ORA-00001: unique constraint (MCDONAC.UM_QUEST) violated ORA-06512: at "MCDONAC.INSERT_QUESTION_PROC", line 12 ORA-06512: at line 2 SQL> SQL> BEGIN 2 INSERT_QUESTION_PROC('f1','E',2001,NULL,1); 3 END; 4 / about to update BEGIN * ERROR at line 1: ORA-00001: unique constraint (MCDONAC.UM_QUEST) violated ORA-06512: at "MCDONAC.INSERT_QUESTION_PROC", line 12 ORA-06512: at line 2 SQL>
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。