Динамическое создание и выполнение команд SQL в Oracle - PullRequest
1 голос
/ 17 февраля 2010

Я беру класс базы данных, и в начале лабораторного раздела класса мы обычно отбрасываем все таблицы в базе данных, созданной ранее. Я хотел иметь возможность запускать скрипт, который делает это динамически, но не может заставить его работать. Вот код, который у меня есть.

declare tname string(50);
cursor ctable is select table_name from user_tables;

begin
 open ctable;
 LOOP
   FETCH ctable into tname;
   if tname != ''  then
     execute immediate 'drop table ' || tname;
   END if;
   EXIT WHEN ctable%NOTFOUND;
 END LOOP;
 close ctable;
end;

Если бы кто-то мог указать мне правильное направление относительно того, что я делаю неправильно, это было бы здорово. Спасибо.

1 Ответ

5 голосов
/ 17 февраля 2010

Oracle VARCHAR2 обрабатывает пустые строки как NULL.Таким образом,

if tname != '' then

- это то же самое, что и

if tname != NULL then

, который вернет NULL вместо TRUE, поскольку он не определен.NULL от tname IS NOT NULL.

table_name является обязательным в user_tables, поэтому такая проверка не требуется.


Еще две вещи:

  1. Проверьте %NOTFOUND сразу после извлечения
  2. Используйте ссылки на столбцы для объявлений переменных, если это возможно (user_tables.table_name%TYPE)

Так ваш код может выглядеть так:

DECLARE
  tname user_tables.table_name%TYPE;
  CURSOR ctable IS SELECT table_name FROM user_tables;
BEGIN
  OPEN ctable;
  LOOP
    FETCH ctable INTO tname;
    EXIT WHEN ctable%NOTFOUND;
    EXECUTE IMMEDIATE 'drop table ' || tname;
  END LOOP;
  CLOSE ctable;
END;

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

BEGIN
  FOR cur IN ( SELECT table_name FROM user_tables ) LOOP
    EXECUTE IMMEDIATE 'drop table ' || cur.table_name;
  END LOOP;
END;
...