PL/SQL 使用 Oracle Apex - 删除验证

PL/SQL with Oracle Apex - Delete Validation

假设我有两个 oracle table: TEST_ENTRIES:

ID 姓名 CAT_ID
1 办公桌 1
2 扶手椅 1
3 其他业务内容 2

和TEST_CATEGORIES:

ID 姓名 可见
1 家具 1
2 消耗品 1

我现在想在 PL/SQL 中的 Oracle Apex 中编写一个验证,它检查 table TEST_CATEGORIES 是否在 TEST_ENTRIES 中使用了某个 id,如果它不使用它应该被删除。因此我写了这样的东西:

Declare
  id number;
Begin
  Select count(1) into id 
   from TEST_CATEGORIES
   Where name = :NAME;

  if id > 0 then
        raise_application_error(-20001,'Could not delete from sepecified tables');
  else
    DELETE FROM TEST_CATEGORIES
    WHERE ID = TEST_ENTRIES.CAT_ID
        RETURN;
  end if;
End;

但是这样不行。有人能帮帮我吗?

可以这样做,但这不是验证的目的。验证意味着 验证 用户输入。例如,如果用户不能选择在结束日期之后的开始日期——这可能会导致验证失败。如果验证失败,则不会执行页面处理。

a 页面流程 用于使用遗留流程或自定义流程执行 dml 操作 (update/insert/delete) pl/sql

您在问题中提到 使用了某个 ID - 这是什么意思?它是用户在表单中选择的值吗?我假设它是我下面代码中的一个页面项目

在您的情况下,代码将分为两部分

验证
SELECT 1 
   FROM test_categories
   WHERE name = :P1_NAME;
页面处理
BEGIN
  DELETE FROM test_categories WHERE name = :P1_NAME;
END;

请注意,我没有关注代码,但更多关注在此示例中, 逻辑应该放在 APEX 中。正如@Littlefoot 指出的那样,最好使用外键约束来防止意外删除。

如果我是你,我会创建一个外键约束并让数据库处理它。像这样:

示例数据:

SQL> select * from test_categories;

        ID NAME           VISIBLE
---------- ----------- ----------
         1 furniture            1
         2 consumables          1
         3 delete me            1    --> not referenced from TEST_ENTRIES table

SQL> select * from test_entries;

        ID NAME         CAT_ID
---------- -------- ----------
         1 desk              1
         2 armchair          1
         3 other             2

给TEST_CATEGORIES添加一个主键(否则外键无法引用):

SQL> alter table test_categories add constraint pk_cat
  2    primary key (id);

Table altered.

添加外键到TEST_ENTRIES:

SQL> alter table test_entries add constraint fk_ent_cat
  2    foreign key (cat_id)
  3    references test_categories (id);

Table altered.

测试:ID = 1 是从 TEST_ENTRIES 引用的,因此 Oracle 不会让您删除它:

SQL> delete from test_categories where id = 1;
delete from test_categories where id = 1
*
ERROR at line 1:
ORA-02292: integrity constraint (SCOTT.FK_ENT_CAT) violated - child record
found

但是,ID = 3 未被引用,将被成功删除:

SQL> delete from test_categories where id = 3;

1 row deleted.

SQL>

如果您想创建自己的代码,方法如下;我 运行 它在 SQL*Plus 中,所以我使用替换变量 &&P1_CAT_ID。取而代之的是,您将使用 :P1_CAT_ID(即页面项目)并省略第 14 行,因为它在 Apex 中无用。

SQL> rollback;

Rollback complete.

SQL> declare
  2    l_cnt number;
  3  begin
  4    select count(*)
  5      into l_cnt
  6      from test_entries e
  7      where e.cat_id = &&P1_CAT_ID;         --> you'd use :P1_CAT_ID
  8
  9    if l_cnt > 0 then
 10       raise_application_error(-20000, 'Not allowed, child records exist');
 11    else
 12       delete from test_categories
 13         where id = &&P1_CAT_ID;            --> you'd use :P1_CAT_ID
 14       dbms_output.put_line(sql%rowcount ||' row(s) deleted');
 15    end if;
 16  end;
 17  /
Enter value for p1_cat_id: 1
declare
*
ERROR at line 1:
ORA-20000: Not allowed, child records exist
ORA-06512: at line 10


SQL> undefine p1_cat_id
SQL> /
Enter value for p1_cat_id: 3
1 row(s) deleted

PL/SQL procedure successfully completed.

SQL>