Я пытаюсь использовать приведенный ниже код для создания таблицы в PL/SQL:
DECLARE
V_NAME VARCHAR2(20);
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE TEMP(NAME VARCHAR(20))';
EXECUTE IMMEDIATE 'INSERT INTO TEMP VALUES(''XYZ'')';
SELECT NAME INTO V_NAME FROM TEMP;
END;
/
Оператор SELECT завершается с ошибкой:
PL/SQL: ORA-00942: table or view does not exist
Возможно ли CREATE, INSERT and SELECT все в одном блоке PL/SQL один за другим?
Ответ 1 · рейтинг 13 · Ben
Я предполагаю, что вы делаете что-то вроде следующего:
declare
v_temp varchar2(20);
begin
execute immediate 'create table temp(name varchar(20))';
execute immediate 'insert into temp values(''XYZ'')';
select name into v_name from temp;
end;
Во время компиляции таблица TEMP не существует. Он еще не создан. Поскольку его не существует, вы не можете выбрать из него; поэтому вы также должны выполнять SELECT динамически. На самом деле нет необходимости выполнять SELECT в этой конкретной ситуации, хотя вы можете использовать returning into.
declare
v_temp varchar2(20)
begin
execute immediate 'create table temp(name varchar2(20))';
execute immediate 'insert into temp
values(''XYZ'')
returning name into :1'
returning into v_temp;
end;
Однако необходимость динамического создания таблиц обычно указывает на плохо спроектированную схему. Это не должно быть необходимо.
Я могу порекомендовать сообщение Рене Ниффенеггера "Почему динамический SQL - это плохо?" по причинам, по которым вам следует избегать динамического SQL, если это вообще возможно, с точки зрения производительности. Также имейте в виду, что вы гораздо более открыты для SQL инъекции и должны использовать переменные связывания и DBMS_ASSERT a> чтобы защититься от него.
Ответ 2 · рейтинг 2 · Gourabp
Если вы запустите программу несколько раз, вы получите сообщение об ошибке даже после изменения программы для запуска оператора select как динамического SQL или использования предложения return into. Потому что, когда вы запускаете программу в первый раз, она создаст таблицу без каких-либо проблем, но когда вы запустите ее в следующий раз, поскольку таблица уже создана в первый раз, и у вас нет оператора удаления, это вызовет ошибку: "Таблица уже существует в База Данных". Поэтому я предлагаю перед созданием таблицы в программе pl/sql всегда проверять, существует ли уже какая-либо таблица с таким же именем в базе данных или нет. Вы можете выполнить эту проверку, используя представления словаря данных/системные таблицы, в которых хранятся метаданные в зависимости от типа вашей базы данных.
Например, в Oracle вы можете использовать следующие представления, чтобы решить, нужно ли создавать таблицы или нет:
БД_ТАБЛИЦЫ, ВСЕ_ТАБЛИЦЫ, ПОЛЬЗОВАТЕЛЬСКИЕ_ТАБЛИЦЫ