ro如何存储rowids以便在删除相应的子记录后将其删除
How ro store rowids in order to delete them after corresponding child records are deleted
我想删除我收集的某些行 select:
DELETE from REMINDER
where exists
(
SELECT r.rowid
FROM reminder r
inner join reminder_users u on u.reminder_id = r.id
inner join device d on d.id = (regexp_replace(r.origin_values, '[^0-9]', '')) and d.NEXT_TEST_DATE_INTERNAL <> u.deadline
inner join device_test t on t.id = d.NEXT_TEST_INT_ID
where u.receipt = 0 and t.TEST_INTERNAL_EXTERNAL = 0 and r.NAME like '%Interne%' and r.NAME not like '%Externe%' and u.DEADLINE > sysdate
);
问题是,有一个 table 'reminder_users' 包含父 table 'Reminder' 的子记录。所以我必须先使用以下语句删除子记录:
DELETE from REMINDER_USERS
where exists
(
SELECT u.ROWID
from reminder_users u
inner join reminder r on r.id = u.reminder_id
inner join device d on d.id = (regexp_replace(r.origin_values, '[^0-9]', '')) and d.NEXT_TEST_DATE_INTERNAL <> u.deadline
inner join device_test t on t.id = d.NEXT_TEST_INT_ID
where u.receipt = 0 and t.TEST_INTERNAL_EXTERNAL = 0 and r.NAME like '%Interne%' and r.NAME not like '%Externe%' and u.DEADLINE > sysdate
);
当我执行第二个操作时,第一个语句return显然是零行,因为我删除了子记录。这就是为什么我正在寻找一种方法来存储第一个操作的 rowid,然后删除子记录,最后从 table 'REMINDER'.
中删除以前存储的数据
我必须在这里使用 CURSOR 吗? (注意:如果查询 return 行,总会有至少 2 行受到影响)。我试图声明一个存储行的变量,但随后出现 'ORA-01422: exact fetch returns more than requested number of rows' 错误...
提前致谢!
你绝对应该在 reminder
和 reminder_users
之间有一个外键约束。如果 reminder_users
中有子记录,您不应该 能够 从 reminder
中删除。这只是基本的数据库参照完整性。
如果该外键定义为 on delete cascade
,您就完成了。删除 reminder
将删除 reminder_users
.
中的相关记录
假设您不能那样做,您可以做的一件事是先获取要删除的 ID,然后再删除它们。您需要创建架构级别 type
:
create type id_tt as table of number;
declare
l_reminder_ids id_tt;
begin
select r.id
bulk collect into l_reminder_ids
from reminder r
inner join reminder_users u on u.reminder_id = r.id
inner join device d
on d.id = (regexp_replace(r.origin_values, '[^0-9]', ''))
and d.NEXT_TEST_DATE_INTERNAL <> u.deadline
inner join device_test t on t.id = d.NEXT_TEST_INT_ID
where u.receipt = 0
and t.TEST_INTERNAL_EXTERNAL = 0
and r.NAME like '%Interne%'
and r.NAME not like '%Externe%'
and u.DEADLINE > sysdate
for update;
delete from reminder_users where reminder_id member of l_reminder_ids;
delete from reminders where id member of l_reminder_ids;
end;
for update
子句用于防止其他会话进入并在您从 reminder_users 中删除时弄乱这些行。 (嗯,现在我考虑了一下,这里可能没有必要。)这假设您尝试删除的行数是“合理的”。如果您尝试删除 2000 万行,这可能不会有很好的性能。
如果@EJEgyed 建议的“on delete cascade”对您可用,那么这就是方法。但是许多 DBA(包括我自己)通常不允许这样做。副作用被认为太危险了。您可能不知道究竟删除了什么,Oracle 也不会告诉您,它只是删除了。如果是这种情况,您有几个选择。
- 只是重复子查询。那会成就你的
需要。
- 运行 在第一次删除中使用“返回...批量收集”的脚本,
第二个是“forall ... delete”。 (参见 demo)。
declare
type rem_list_t is table of reminder_users.rem_id%type;
ren_list rem_list_t;
begin
delete
from reminder_users
where rem_id in ( select rem_id
from reminders
where rem_id in
(select to_char(floor(dbms_random.value(1,200)))
from dual connect by level <= 4
)
and message not like '%Event #6' )
returning rem_id
bulk collect
into ren_list;
dbms_output.put_line( 'Rows deleted from reminder_users:' || to_char(sql%rowcount));
forall ru in 1 .. ren_list.count
delete
from reminders
where rem_id = ren_list(ru);
dbms_output.put_line( 'Rows deleted from reminders:' || to_char(sql%rowcount));
end ;
一句警告。您当前的查询格式不正确。他们将删除 0 行,因为子选择没有满足 where 条件,或者它将删除 All ROWS,因为至少有 1 行满足 where 条件。如果 1 行或多行满足条件,则 EXIST 谓词的计算结果为真,但外部条件中的每一行都为真。演示,还包含一个示例。我没有您的 table 定义或示例数据,因此该演示基于简单的 table/query,但保持与您的 SQL.
相同的结构
我想删除我收集的某些行 select:
DELETE from REMINDER
where exists
(
SELECT r.rowid
FROM reminder r
inner join reminder_users u on u.reminder_id = r.id
inner join device d on d.id = (regexp_replace(r.origin_values, '[^0-9]', '')) and d.NEXT_TEST_DATE_INTERNAL <> u.deadline
inner join device_test t on t.id = d.NEXT_TEST_INT_ID
where u.receipt = 0 and t.TEST_INTERNAL_EXTERNAL = 0 and r.NAME like '%Interne%' and r.NAME not like '%Externe%' and u.DEADLINE > sysdate
);
问题是,有一个 table 'reminder_users' 包含父 table 'Reminder' 的子记录。所以我必须先使用以下语句删除子记录:
DELETE from REMINDER_USERS
where exists
(
SELECT u.ROWID
from reminder_users u
inner join reminder r on r.id = u.reminder_id
inner join device d on d.id = (regexp_replace(r.origin_values, '[^0-9]', '')) and d.NEXT_TEST_DATE_INTERNAL <> u.deadline
inner join device_test t on t.id = d.NEXT_TEST_INT_ID
where u.receipt = 0 and t.TEST_INTERNAL_EXTERNAL = 0 and r.NAME like '%Interne%' and r.NAME not like '%Externe%' and u.DEADLINE > sysdate
);
当我执行第二个操作时,第一个语句return显然是零行,因为我删除了子记录。这就是为什么我正在寻找一种方法来存储第一个操作的 rowid,然后删除子记录,最后从 table 'REMINDER'.
中删除以前存储的数据我必须在这里使用 CURSOR 吗? (注意:如果查询 return 行,总会有至少 2 行受到影响)。我试图声明一个存储行的变量,但随后出现 'ORA-01422: exact fetch returns more than requested number of rows' 错误...
提前致谢!
你绝对应该在 reminder
和 reminder_users
之间有一个外键约束。如果 reminder_users
中有子记录,您不应该 能够 从 reminder
中删除。这只是基本的数据库参照完整性。
如果该外键定义为 on delete cascade
,您就完成了。删除 reminder
将删除 reminder_users
.
假设您不能那样做,您可以做的一件事是先获取要删除的 ID,然后再删除它们。您需要创建架构级别 type
:
create type id_tt as table of number;
declare
l_reminder_ids id_tt;
begin
select r.id
bulk collect into l_reminder_ids
from reminder r
inner join reminder_users u on u.reminder_id = r.id
inner join device d
on d.id = (regexp_replace(r.origin_values, '[^0-9]', ''))
and d.NEXT_TEST_DATE_INTERNAL <> u.deadline
inner join device_test t on t.id = d.NEXT_TEST_INT_ID
where u.receipt = 0
and t.TEST_INTERNAL_EXTERNAL = 0
and r.NAME like '%Interne%'
and r.NAME not like '%Externe%'
and u.DEADLINE > sysdate
for update;
delete from reminder_users where reminder_id member of l_reminder_ids;
delete from reminders where id member of l_reminder_ids;
end;
for update
子句用于防止其他会话进入并在您从 reminder_users 中删除时弄乱这些行。 (嗯,现在我考虑了一下,这里可能没有必要。)这假设您尝试删除的行数是“合理的”。如果您尝试删除 2000 万行,这可能不会有很好的性能。
如果@EJEgyed 建议的“on delete cascade”对您可用,那么这就是方法。但是许多 DBA(包括我自己)通常不允许这样做。副作用被认为太危险了。您可能不知道究竟删除了什么,Oracle 也不会告诉您,它只是删除了。如果是这种情况,您有几个选择。
- 只是重复子查询。那会成就你的 需要。
- 运行 在第一次删除中使用“返回...批量收集”的脚本, 第二个是“forall ... delete”。 (参见 demo)。
declare
type rem_list_t is table of reminder_users.rem_id%type;
ren_list rem_list_t;
begin
delete
from reminder_users
where rem_id in ( select rem_id
from reminders
where rem_id in
(select to_char(floor(dbms_random.value(1,200)))
from dual connect by level <= 4
)
and message not like '%Event #6' )
returning rem_id
bulk collect
into ren_list;
dbms_output.put_line( 'Rows deleted from reminder_users:' || to_char(sql%rowcount));
forall ru in 1 .. ren_list.count
delete
from reminders
where rem_id = ren_list(ru);
dbms_output.put_line( 'Rows deleted from reminders:' || to_char(sql%rowcount));
end ;
一句警告。您当前的查询格式不正确。他们将删除 0 行,因为子选择没有满足 where 条件,或者它将删除 All ROWS,因为至少有 1 行满足 where 条件。如果 1 行或多行满足条件,则 EXIST 谓词的计算结果为真,但外部条件中的每一行都为真。演示,还包含一个示例。我没有您的 table 定义或示例数据,因此该演示基于简单的 table/query,但保持与您的 SQL.
相同的结构