Oracle процедура удаления записей во всех таблицах владельца - PullRequest
0 голосов
/ 14 января 2020

Я пытаюсь создать Oracle процедуру для удаления записей из нескольких таблиц владельца на основе отдельного условия подсчета:

Сначала я пытаюсь получить таблицы, для которых я хочу удалить те записей с этим запросом:

SELECT * FROM ALL_TABLES WHERE OWNER = 'Lorik' AND TABLE_NAME LIKE 'UT_%';

В результате получается 300 таблиц, теперь у всех этих таблиц есть столбец с именем: DATE_IN C

Я пытаюсь удалить записи из все таблицы , если этот COUNT (DISTINCT DATE_IN C)> 5. Предполагается, что одна из этих 300 таблиц имеет имя UT_NAMES:

SELECT COUNT(DISTINCT DATE_INC) FROM Lorik.UT_NAMES;

То есть, если число превышает 5, затем я хочу удалить записи с минимальной датой:

DELETE MIN(DATE_INC) FROM Lorik.UT_NAMES;

Может ли кто-нибудь связать эти шаги вместе, чтобы я мог oop просмотреть каждую таблицу этого владельца и получить различное количество дат и удалить записи на основании приведенного выше условия.

Заранее спасибо!

Ответы [ 3 ]

1 голос
/ 14 января 2020

Как отмечает @Andrew, это кажется очень базовым c процессами.

  • Объявление некоторых переменных.
  • Открытие курсора.
  • Использование Dynami c sql для подсчета
  • Используйте Dynami c sql для удаления
  • Добавьте некоторую информацию журнала

_

declare 
    v_cnt   number;
    v_sql   varchar2(1000);
begin
    for cur in (SELECT * FROM ALL_TABLES WHERE OWNER = 'HR' AND TABLE_NAME LIKE 'E%')
    loop
        v_sql := 'select count(distinct department_id||''date_inc'') from '||cur.owner||'. '||cur.table_name;
        execute immediate v_sql into v_cnt;
        dbms_output.put_line (cur.table_name || ': ' || v_cnt);
        if v_cnt > 5 then
            v_sql := 'delete from '||cur.owner||'. '||cur.table_name || ' where date_inc = (select min (date_inc) from ' ||cur.owner||'. '||cur.table_name || ')';
            dbms_output.put_line (v_sql);
            -- execute immediate v_sql;
        end if;
    end loop;
    rollback;
    -- commit;
end;
1 голос
/ 14 января 2020

Вы можете использовать 'EXECUTE IMMEDIATE' в PL / SQL для достижения sh вашей цели:

DECLARE
  strTable  VARCHAR2(32767);
  nCount    NUMBER;
BEGIN
  FOR aRow IN (SELECT *
                 FROM ALL_TABLES
                 WHERE OWNER = 'Lorik' AND
                       TABLE_NAME LIKE 'UT_%')
  LOOP
    strTable := aRow.OWNER || '.' || aRow.TABLE_NAME;

    EXECUTE IMMEDIATE 'SELECT COUNT(DISTINCT DATE_INC) FROM ' || strTable
      INTO nCount;

    IF nCount > 5 THEN
      EXECUTE IMMEDIATE 'DELETE FROM ' || strTable ||
                           ' WHERE DATE_INC = (SELECT MIN(DATE_INC) ' ||
                                                 'FROM ' || strTable || ')';
    END IF;
  END LOOP;
END;

Не тестировали на животных - вы будете первыми! : -)

0 голосов
/ 14 января 2020

Немного проще Dynami c SQL для удаления строк, так как он использует локальную переменную:

declare
  l_cnt      number;       -- counter variable
  l_min_date date;         -- MIN(date_inc)
begin
  for cur_t in (select table_name from all_tables 
                where owner = 'Lorik'          -- are you sure it is not uppercase, LORIK?
                  and table_name like 'UT%'    -- underline is wildcard character so you don't need it
               )
  loop
    execute immediate 'select count(distinct date_inc), min(date_inc) from ' || 
                       cur_t.table_name into l_cnt, l_min_date;
    if l_cnt > 5 then
       execute immediate 'delete from ' || cur_t.table_name ||
                         '  where date_inc = ' || l_min_date_inc;
    end if;
  end loop;
end;
/ 
...