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>
假设我有两个 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>