约束在我自己的过程中停止DELETE,但是同样的DELETE在SQLPlus中运行

时间:2017-04-02 04:21:14

标签: oracle stored-procedures sqlplus referential-integrity

在我自己的Package.Procedure中运行两个DELETE语句:

DELETE FROM ENT_PLANT_RELATIVE WHERE CHILD_ID = plant_id;
DELETE FROM ENT_PLANT_ITEM WHERE PLANT_ID = plant_id;

...我在第二个DELETE上收到完整性约束违规(首先正常工作):

SQL> call P.DeletePlantItem(112808,1,:err);
ORA-02292: integrity constraint
(XXXXX.EAITA_PLANT_ITEM_ID_FK) violated - child record found

表中没有包含FK的子记录,其中包含该名称的约束:

SQL> select count(plant_item_id) from ent_application_item_to_access 
where plant_item_id = 112808;

COUNT(PLANT_ITEM_ID)
--------------------
                   0

...该表中只有一列使用PLANT_ITEM_ID。

在SQL * Plus中直接运行可疑DELETE语句(从程序中复制)(我称之为程序),它按预期工作。

我有:

  • 禁用显示的第一个完整性约束,仅在另一个表上显示另一个类似的约束,同样不包含FK
  • 禁用显示的第二个类似的完整性约束... ditto
  • 将单个记录插入主表和我尝试删除的一个子表,并再次尝试使用与先前现有记录相同的结果
  • 将一个项目手动插入ENT_PLANT_ITEM,在过程中注释掉了不必要的DELETE,然后尝试调用它:相同的结果
  • 在子表(ENT_PLANT_RELATIVE)第一次(成功)删除后立即尝试COMMIT
  • 使用put_line获取上面显示的SQLERRM包含标识约束
  • 检查是否存在触发器插入记录(不必要的是,我觉得,因为表中没有显示约束问题的子数据)
  • 使用IF在逻辑上将过程分解为两个单独的过程,分别处理两个DELETE语句:相同的结果
  • 尽可能多地检查权限,虽然我认为因为我可以从一个上下文(SQLPlus)DELETE,并且首先创建包和过程,我应该能够从过程中(呼叫)
  • 还假设SQLERRM将报告权限错误
  • 阅读有关约束的在线Oracle文档
  • 阅读尽可能多的Stack Overflow问题,因为我可以找到引用约束和参照完整性的问题

包裹定义是:

CREATE OR REPLACE PACKAGE P AS 
    PROCEDURE InsertPlantItem(plant_desc IN VARCHAR2, parent_desc IN VARCHAR2, test IN NUMBER, err OUT VARCHAR2);
    PROCEDURE DeletePlantItem(plant_id IN NUMBER, test IN NUMBER, err OUT VARCHAR2);
END P;

总之,为什么我可以从SQL * Plus命令行删除表y中的行x,但不能通过我创建的存储过程删除,因为表中的约束我没有任何键?

1 个答案:

答案 0 :(得分:1)

问题确实存在于第二个DELETE声明中:

DELETE FROM ENT_PLANT_ITEM WHERE PLANT_ID = plant_id;

我创建了一个名为IN的{​​{1}}参数,传入一个6位数的数字,但没有意识到我有效地要求程序删除数据库中的所有项目约束并没有阻止它。它在所有首都都相当明显:

plant_id

列名显然优先于参数。