Exception 捕获唯一索引冲突并引发应用程序错误

Exception 捕获唯一索引冲突并引发应用程序错误,exception,oracle11g,unique-constraint,unique-index,Exception,Oracle11g,Unique Constraint,Unique Index,是否可能捕获唯一索引冲突并引发应用程序错误。我们正在尝试使用一揽子触发器并捕获异常,但是我们总是得到oracle异常 ORA-00001:违反唯一约束(测试唯一索引) 我们在表上有一个基于函数的约束 CREATE TABLE TEST_CONSTRAINT( "ID" NUMBER NOT NULL ENABLE, "LOCATION" VARCHAR2(20) NOT NULL, "DEPT" VARCHAR2(20) NOT NULL, "RECORD"

是否可能捕获唯一索引冲突并引发应用程序错误。我们正在尝试使用一揽子触发器并捕获异常,但是我们总是得到oracle异常

ORA-00001:违反唯一约束(测试唯一索引)

我们在表上有一个基于函数的约束

CREATE TABLE TEST_CONSTRAINT(
    "ID" NUMBER NOT NULL ENABLE, 
    "LOCATION" VARCHAR2(20) NOT NULL, 
    "DEPT" VARCHAR2(20) NOT NULL, 
    "RECORD" NUMBER NOT NULL)
/
CREATE UNIQUE INDEX TEST_UNIQUE_INDEX ON TEST_CONSTRAINT (
    CASE "RECORD" WHEN 1 THEN "LOCATION" ELSE NULL END, 
    CASE "RECORD" WHEN 1 THEN "DEPT"     ELSE NULL END)
/
在更新触发代码之前

EXCEPTION 
  WHEN DUP_VAL_ON_INDEX THEN
      ERROR_MESSAGE := SQLERRM;
      DBMS_OUTPUT.PUT_LINE('SQLERRM '|| ERROR_MESSAGE);
  WHEN OTHERS THEN
      ERROR_MESSAGE := SQLERRM;
      DBMS_OUTPUT.PUT_LINE('SQLERRM '|| ERROR_MESSAGE);     
END;

编辑1:


此处的要求是施加选择性唯一性,即只能将一组位置/部门设置为记录(在应用程序中为布尔值)。在所有其他情况下,我们必须生成raise_应用程序_错误

触发器将在更新发生之前执行。由于在执行过程中不会出现异常(它所做的只是打印系统日期),因此不会引发异常。然后,实际执行更新,此时您从数据库中获得错误消息

要捕获由于UPDATE语句而发生的异常,UPDATE语句本身必须包含在PL/SQL块中,如下所示

DECLARE 
  V_DATE DATE;
  ERROR_MESSAGE VARCHAR2(1000); 
BEGIN
  SELECT SYSDATE INTO V_DATE FROM DUAL;
  DBMS_OUTPUT.PUT_LINE('SYSDATE '|| V_DATE);

  UPDATE TEST_CONSTRAINT SET RECORD = 1 WHERE ID = 3;

EXCEPTION 
  WHEN DUP_VAL_ON_INDEX THEN
      ERROR_MESSAGE := SQLERRM;
      DBMS_OUTPUT.PUT_LINE('Error occurred. SQLERRM '|| ERROR_MESSAGE);
  WHEN OTHERS THEN
      ERROR_MESSAGE := SQLERRM;
      DBMS_OUTPUT.PUT_LINE('SQLERRM '|| ERROR_MESSAGE);     
END;
/
参考


我不能使用pl/sql块,因为这些更新是从应用程序api触发的。因此,我们需要捕捉这些错误并显示相应的错误消息。如果可以在数据库中使用UPDATE语句创建一个过程,那么您可以调用该过程来执行更新。另外,如果新值将导致“重复”行,则可以考虑首先从APP API本身检查。如果他们愿意,那么您可以选择不执行更新。