根据一个连接的结果删除两个表。
根据一个连接的结果删除两个表。
我正在尝试使用内连接同时从两个表中删除数据。然而,当我尝试运行我的查询时,出现了一个错误“SQL命令结束不正确”的错误。
我想简要说明一下我正在尝试做的事情以及表table1和table2的一些信息。所以这两个表都有一个相同的字段,比如“ABC”。我想使用内连接从两个表中删除数据,但是在一个字段(XYZ)的where条件下,它等于一个值。
这是我的SQL语句:
DELETE table1, table2 FROM table1 INNER JOIN table1 ON table1.ABC = table2.ABC WHERE table1.XYZ = 'TESTIT';
在Oracle中,你不能像你正在做的那样在一个语句中从两个表中删除数据。语法是错误的。你可以像下面这样使用:
DELETE table1 where table1.ABC = (select table2.ABC from table2 WHERE table2.ABC = table1.ABC and table1.XYZ = 'TESTIT');
不需要使用`FROM`吗?
在Oracle中,`FROM`是可选的。
是吗?谢谢你的信息。
但请注意,它只是在`DELETE`语句中是可选的,而在`SELECT`语句中是不可选的 🙂
嗨,谢谢你的回复,但是我如何删除第二个表?我需要更改查询中表的位置吗?
这是一个相关子查询。所以更改表名并匹配条件,然后行将被删除,你需要尝试一下。
不是。当首先从table1中删除记录时,你无法查找这些记录以便从table2中删除 - 它们将消失 🙂
你没有回答问题,`ABC`是否是表的主键或唯一键。`table2.ABC`是唯一的吗?`table1.ABC`是唯一的,或者可能是`table1.ABC` + `table1.XYZ`?对这些问题的回答可能会有很大的不同。
我没有说如果条件匹配记录将被删除,这是常识,如果我从表中删除了记录,条件将永远不会匹配。是吗?
嗯,也许我误解了。但是你展示的是如何从其中一个表中删除的。楼主问的是如何从另一个表中删除。你说:相应地更改语句。但是怎么改?楼主想要在t2中有匹配时从t1中删除,在t1中有匹配时从t2中删除。所以如果你先从一个表中删除,然后再从另一个表中删除,因为查找数据将会消失,你就无法再删除了。
坦率地说,问题不清楚,我们不知道楼主实际想要做什么。我只是给出了一个示例,因为他实际查询是不正确的。其他的澄清你自己问吧。
问题的原因是无法同时删除两个表,需要使用两个不同的DELETE语句来分别删除两个表。解决方法是创建一个临时表来存储要删除的ID,然后使用DELETE语句分别删除两个表中与临时表中的ID相匹配的记录,最后再删除临时表。
具体解决方法如下:
1. 创建一个名为app的临时表,该表包含一个名为ABC的varchar(100)类型的列。
CREATE TABLE app (ABC varchar(100));
2. 将table1和table2中满足条件table1.XYZ = 'TESTIT'的记录的ABC字段插入到app表中。
INSERT INTO app (ABC) SELECT abc FROM table1 INNER JOIN table1 ON table1.ABC = table2.ABC WHERE table1.XYZ = 'TESTIT';
3. 使用DELETE语句从table1中删除与app表中的ABC字段相匹配的记录。
DELETE FROM table1 WHERE table1.ABC IN (SELECT ABC FROM app);
4. 使用DELETE语句从table2中删除与app表中的ABC字段相匹配的记录。
DELETE FROM table2 WHERE table2.ABC IN (SELECT ABC FROM app);
5. 删除app表。
DROP TABLE app;
通过以上步骤,可以实现基于一个JOIN的结果删除两个表的操作。
问题的出现原因:
根据给出的PL/SQL代码,问题是要根据一次连接的结果删除两个表中的数据。具体来说,根据表1和表2之间的连接,从表1和表2中删除满足条件xyz = 'TESTIT'
的数据。
解决方法:
解决方法是使用PL/SQL中的FORALL语句,通过循环遍历连接结果集中的每个元素,并使用DELETE语句从表1和表2中删除满足条件的数据。首先,通过SELECT语句将满足条件xyz = 'TESTIT'
的表1的abc
列的唯一值存储在一个集合中。然后,使用FORALL语句和DELETE语句从表1和表2中删除满足条件的数据。最后,使用DBMS_OUTPUT.PUT_LINE语句输出删除的行数。
下面是完整的解决方案代码:
declare type abc_tt is table of table1.abc%type index by pls_integer; l_abc_collection abc_tt; begin select distinct t1.abc bulk collect into l_abc_collection from table1 t1 join table2 t2 on t2.abc = t1.abc where t1.xyz = 'TESTIT'; dbms_output.put_line('Stored ' || l_abc_collection.count || ' values for processing'); forall i in 1..l_abc_collection.count delete table1 t where t.xyz = 'TESTIT' and t.abc = l_abc_collection(i); dbms_output.put_line('Deleted ' || sql%rowcount || ' rows from table1'); forall i in 1..l_abc_collection.count delete table2 t where t.xyz = 'TESTIT' and t.abc = l_abc_collection(i); dbms_output.put_line('Deleted ' || sql%rowcount || ' rows from table2'); end;
运行此代码后,输出如下:
Stored 1000 values for processing Deleted 1000 rows from table1 Deleted 1000 rows from table2
测试设置:
create table table1 (abc, xyz) as select rownum, 'TESTIT' from dual connect by rownum <= 1000 union all select rownum, 'OTHER' from dual connect by rownum <= 100; create table table2 as select * from table1;
在删除之后,每个表中都有100行数据。假设我们只想删除xyz = 'TESTIT'
的行,即使abc
的值在两个表中是相同的。