【问题标题】:ORA-00001: unique constraint (SYSTEM.BROWSERS_PK) violatedORA-00001: 违反唯一约束 (SYSTEM.BROWSERS_PK)
【发布时间】:2014-11-06 23:30:24
【问题描述】:

我正在处理一个 C# 项目,我正在尝试使用以下 SQL 对 Oracle 数据库插入一条记录:

String Qry = INSERT INTO browsers (browsers.browser,browsers.engine,browsers.platform,browsers.version,browsers.grade) VALUES ('Alans browser','Gecko','every','1.0','U') RETURNING id INTO :ID

我正在关注示例代码:http://www.sqlines.com/oracle-to-sql-server-cs-conversion/insert-returning-clause

我的代码如下:

OracleConnection conn = new OracleConnection(...);
OracleCommand cmd = null;
...
cmd = new OracleCommand(Qry, conn);
OracleParameter prm = new OracleParameter();
prm = new OracleParameter(":ID", OracleDbType.Int32, ParameterDirection.ReturnValue);
cmd.Parameters.Add(prm);
cmd.ExecuteNonQuery(); //this line throws error
query.setNewRecordID(cmd.Parameters[":ID"].Value.ToString());
...

当然,浏览器表的 id 列设置了 Sequence 和 Trigger 以在任何插入时自动递增。当我不尝试设置 id 列时,我不明白为什么会出现错误。我只是想检索赋予新记录的 id 值。

Uddate:以下是创建序列和触发器的 SQL 命令:

顺序:

CREATE SEQUENCE "SYSTEM"."BROWSERS_SEQ" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 21 CACHE 20 NOORDER NOCYCLE NOPARTITION ;

触发器:

create or replace trigger BROWSERS_TRG  
before insert on "SYSTEM"."BROWSERS" 
for each row 
begin  
   if inserting then 
      if :NEW."ID" is null then 
         select BROWSERS_SEQ.nextval into :NEW."ID" from dual; 
      end if; 
   end if; 
end;

【问题讨论】:

  • 您能否通过查询视图 user_triggers 来确认您的触发器的状态是否已启用?我假设触发器是一个类似的“插入前”触发器,并且它插入 browsers_seq 的 NEXTVAL?
  • 我已经为上面的序列和触发器添加了代码。我很确定它们设置正确。我不确定如何查询您所说的视图。你能告诉我查询是什么样的,以便我进行测试吗?
  • 我会运行这样的查询,SELECT * FROM user_triggers WHERE table_name = 'BROWSERS' AND trigger_name = 'BROWSERS_TRG'
  • 好的。我运行了查询。它是成功的。状态栏表明它已启用。
  • 只是想确保状态列指示它是“启用”。该错误表明这似乎不起作用。

标签: c# sql oracle


【解决方案1】:

我认为您的序列存在问题(我无法按原样编译)。我把 NOPARTITION 去掉了,它起作用了。

我在我的 SCOTT(示例)架构中创建了一个类似的场景,如下所示:

 SCOTT@dev> CREATE TABLE "SCOTT"."EMP2"
  2    (
  3      "EMPNO"    NUMBER(4,0),
  4      "ENAME"    VARCHAR2(10 BYTE),
  5      "JOB"      VARCHAR2(9 BYTE),
  6      "MGR"      NUMBER(4,0),
  7      "HIREDATE" DATE,
  8      "SAL"      NUMBER(7,2),
  9      "COMM"     NUMBER(7,2),
 10      "DEPTNO"   NUMBER(2,0)
 11    )
 12    TABLESPACE "SYSTEM" ;

Table created.

SCOTT@dev> CREATE UNIQUE INDEX "SCOTT"."EMP2_EMPNO" ON "SCOTT"."EMP2"
  2    (
  3      "EMPNO"
  4    )
  5    TABLESPACE "SYSTEM" ;

Index created.

SCOTT@dev> set define off;
SCOTT@dev> ALTER TABLE "SCOTT"."EMP2" ADD PRIMARY KEY ("EMPNO");

Table altered.

SCOTT@dev>  CREATE SEQUENCE EMP2_SEQ MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 21 CACHE 20 NOORDER NOCYCLE  ;

Sequence created.

SCOTT@dev> CREATE OR REPLACE TRIGGER EMP2_TRG before
  2    INSERT ON SCOTT.EMP2 FOR EACH row BEGIN IF inserting THEN IF :NEW.EMPNO IS NULL THEN
  3    SELECT EMP2_SEQ.NEXTVAL INTO :NEW.EMPNO FROM dual;
  4  END IF;
  5  END IF;
  6  END;
  7  /

Trigger created.

SCOTT@dev> commit;

Commit complete.

SCOTT@dev> INSERT INTO EMP2
  2  (ENAME)
  3  VALUES
  4  ('FRED')
  5  /

1 row created.

SCOTT@dev> commit;

Commit complete.

因此,序列似乎是罪魁祸首。

【讨论】:

  • 谢谢帕特里克。今天早上我能够重新审视这个问题,并认为必须有一种方法来查询序列本身并找出它当前拥有的价值。通过运行 select browsers_seq.currval from dual 我能够看到最后一个值是 48。我从表中删除了所有大于 48 的记录,并且由于只有少数记录,因此一次重新插入一个而不会出错.所以问题就解决了。感谢您的帮助。
【解决方案2】:

您确定序列和触发器设置正确吗?通常我不使用触发器,而只是将一个 sequencer.nextval 直接放入查询中。如果您需要在代码的其他部分使用生成的 id,您可以执行“select sequence.nextval from dual”并缓存结果

【讨论】:

  • OK 我将查询更改为:INSERT INTO browsers (browsers.ID,browsers.browser,browsers.engine,browsers.platform,browsers.version,browsers.grade) VALUES (BROWSERS_SEQ.NEXTVAL, '艾伦浏览器','Gecko','every','1.0','U');我正在 SQL Developer 中单独测试这个 SQL 语句,看看会发生什么。它本身正在产生错误。我在查询字符串中遗漏了什么吗?该序列绝对命名为 BROWSERS_SEQ
  • 表不为空。那里有 59 条记录,第一条记录以 id=1 开头。
  • 因此,您的序列可能是从表中已经存在的 id 开始的。要增加序列,请将序列 xx 增加 xx
  • 我运行了以下命令: ALTER SEQUENCE "SYSTEM"."BROWSERS_SEQ" MINVALUE 1 MAXVALUE 99999999999999999999999999999 CACHE 20 NOORDER NOCYCLE INCREMENT BY 1;后跟一个 INSERT 语句,但它没有帮助。同样的错误信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多