Oracle удалить из таблицы A, где в таблице B находится повторяющаяся строка - PullRequest
0 голосов
/ 26 сентября 2018

Как видно из заголовка, я ищу способ удалить все строки из таблицы А, где в таблице В есть соответствующая строка.Таблицы A и B содержат около 30 столбцов, поэтому WHERE A.col1 = B.col1 и т. д. будет немного проблематичным.В идеале я надеялся на что-то вроде

DELETE FROM tableA WHERE IN TableB 

(чрезмерно упрощенное подобными вещами)

Ответы [ 4 ]

0 голосов
/ 26 сентября 2018
create table tableA (a NUMBER, b VARCHAR2(5), c INTEGER);
create table tableB (a NUMBER, b VARCHAR2(5), c INTEGER);

Как вы сказали

ГДЕ A.col1 = B.col1 и т. Д. Будет немного проблематично

вы можете пересечь таблицы и указать все столбцыиз таблицы А один раз, вот так:

delete tableA 
 where (a,b,c) in (select * from tableA
                   intersect
                   select * from tableB);
0 голосов
/ 26 сентября 2018

IN предложение может сравнивать все столбцы, возвращаемые из select

DELETE FROM tableA WHERE ( col1,col2,col3,.. ) IN ( select col1,col2,col3... FROM TableB );
0 голосов
/ 26 сентября 2018

Вы можете создать функцию, которая проверяет структуры таблиц и, если они совпадают, создает строку, содержащую правильные условия для сравнения.

Например, вот две таблицы:

create table t1 (id, name, age) as (
  select 1, 'Tom', 67 from dual union all
  select 2, 'Tia', 42 from dual union all
  select 3, 'Bob', 16 from dual );

create table t2 (id, name, age) as (
  select 1, 'Tom', 51 from dual union all
  select 3, 'Bob', 16 from dual );

Теперь используйте функцию:

select generate_condition('T1', 'T2') from dual;

Результат:

T1.ID = T2.ID and T1.NAME = T2.NAME and T1.AGE = T2.AGE

Скопируйте, вставьтеи выполните delete запрос:

delete from t1 where exists (select 1 from t2 where <<PASTE_HERE>>)

Вот функция, настройте ее при необходимости.Я использовал user_tab_columns, поэтому, если таблицы находятся на разных схемах, вам нужно all_tab_columns и сравнить владельцев.Если у вас Oracle 11g, вы можете заменить цикл на listagg().Вторая таблица должна содержать все столбцы первой таблицы, и они должны быть одинакового типа и длины.

create or replace function generate_condition(i_t1 in varchar2, i_t2 in varchar2) 
    return varchar2 is
    v varchar2(1000) := '';
begin
    for rec in (select column_name, u2.column_id
                  from user_tab_cols u1 
                  left join (select * from user_tab_cols where table_name = i_t2) u2
                  using (column_name, data_type, data_length) 
                  where u1.table_name = i_t1 order by u1.column_id) 
    loop
        if rec.column_id is null then 
            v := 'ERR: incompatible structures';
            goto end_loop;
        end if;
        v := v||' and '||i_t1||'.'||rec.column_name
                ||' = '||i_t2||'.'||rec.column_name;
    end loop;
    << end_loop >>
    return(ltrim(v, ' and '));
end;

Если вы хотите избежать запуска процесса вручную, вам нужен динамический PL / SQL.

0 голосов
/ 26 сентября 2018

Простой способ установить, одинаковы ли две записи в каждой таблице, - просто сравнить каждый столбец:

DELETE
FROM tableA a
WHERE EXISTS (SELECT 1 FROM tableB b WHERE a.col1 = b.col1 AND a.col2 = b.col2 AND ...
    a.col30 = b.col30);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...