Oracle - создание динамической c функции для удаления таблиц на основе курсора - PullRequest
0 голосов
/ 07 апреля 2020

Я пытаюсь создать динамическую c функцию в Oracle, используя курсор для всех таблиц, которые необходимо удалить и заново создать. Например, у меня есть следующая примерная структура таблицы:

CREATE TABLE All_tmp_DATA AS
(SELECT 'T_tmp_test1' As Table_NM, 'TEST1' As Process_name FROM DUAL UNION ALL
 SELECT 'T_tmp_test2' As Table_NM, 'TEST1' As Process_name FROM DUAL UNION ALL
 SELECT 'T_tmp_test3' As Table_NM, 'TEST1' As Process_name FROM DUAL)

Приведенные выше таблицы, начинающиеся с "T_tmp", представляют все таблицы в базе данных, которые необходимо отбросить, если их число> 1 при запуске TEST1 обработать. Мне действительно нужна функция для передачи параметра Process_name, где я могу ввести «TEST1», и создать al oop с помощью курсора, привязав его к Table_NM из All_tmp_DATA и вставив его в table_name в следующем коде:

BEGIN  
  SELECT count(*)
    INTO l_cnt
    FROM user_tables
    WHERE table_name = 'MY_TABLE';
  IF l_cnt = 1 THEN
    EXECUTE IMMEDIATE 'DROP TABLE my_table';
  END IF;
END;

Ответы [ 2 ]

0 голосов
/ 07 апреля 2020

Вы можете использовать обработку исключений для непосредственной обработки такого сценария следующим образом:

DECLARE
    TABLE_DOES_NOT_EXIST EXCEPTION;
    PRAGMA EXCEPTION_INIT ( TABLE_DOES_NOT_EXIST, -00942 );
BEGIN
    FOR CUR_R IN (
        SELECT TABLE_NM
          FROM ALL_TMP_DATA
    ) LOOP
        BEGIN
            EXECUTE IMMEDIATE 'drop table "' || cur_r.table_nm || '"';
            DBMS_OUTPUT.PUT_LINE('"' || cur_r.table_nm || '" table dropped.');
        EXCEPTION
            WHEN TABLE_DOES_NOT_EXIST THEN
                DBMS_OUTPUT.PUT_LINE('"' || cur_r.table_nm || '" table does not exists');
        END;
    END LOOP;
END;
/
0 голосов
/ 07 апреля 2020

В начале я бы рекомендовал вам не использовать смешанный регистр при именовании Oracle объектов.


Контрольный пример:

SQL> select * From all_tmp_data;

TABLE_NM    PROCE
----------- -----
T_tmp_test1 TEST1
T_tmp_test2 TEST1
T_tmp_test3 TEST1

SQL> create table "T_tmp_test1" as select * From dept;

Table created.

SQL> -- I don't have "T_tmp_test2"
SQL> create table "T_tmp_test3" as select * From emp;

Table created.

SQL>
SQL> select table_name From user_Tables where upper(table_name) like 'T_TMP%';

TABLE_NAME
------------------------------
T_tmp_test3
T_tmp_test1

Процедура, которая отбрасывает содержащиеся в ней таблицы в ALL_TMP_DATA:

  • , в отличие от вашего кода, я связал имя таблицы с DROP
  • , так как вы используете имена таблиц со смешанным регистром, вы должны заключить их имена в двойные кавычки, всегда (разве я сказал, что не использовал это?)

Как показывает окончательный select, эти таблицы больше не существуют.

SQL> declare
  2    l_cnt number;
  3  begin
  4    for cur_r in (select table_nm from all_tmp_data) loop
  5      select count(*) into l_cnt
  6      from user_tables
  7      where table_name = cur_r.table_nm;
  8
  9      if l_cnt > 0 then
 10         execute immediate ('drop table "' || cur_r.table_nm || '"');
 11      end if;
 12    end loop;
 13  end;
 14  /

PL/SQL procedure successfully completed.

SQL> select table_name From user_Tables where upper(table_name) like 'T_TMP%';

no rows selected

SQL>

По состоянию на столбец process: я понятия не имею, для чего он используется, поэтому я сделал именно это - не использовал его.

...