Oracle Создание локальных таблиц с использованием динамического SQL? - PullRequest
0 голосов
/ 28 октября 2019

Как использовать локальную временную таблицу или альтернативу с использованием динамического SQL в Oracle?

В SQL Server, чтобы выбрать все столбцы из таблицы с именем dbo.2019 в локальную временную таблицу с именем x:

CREATE TABLE #x (a int)

DECLARE @FY varchar(4) = Year(date())

EXEC ('SELECT * into #x FROM dbo.'+@FY)

Причина, по которой я хочу это сделать, заключается в том, что я хочу использовать все виды информации (кроме года, например, значения из других таблиц или что-то еще) для построения очень сложных запросов таким образом, чтобы не требовалось многопричудливые подзапросы.

Ограничение SQL Server заключается в том, что вы должны сначала создать временные таблицы, либо использовать глобальные, чтобы люди могли перезаписывать их.

1 Ответ

1 голос
/ 28 октября 2019

Как известно, Oracle <> MS SQL Server. Последний часто использует временные таблицы. Oracle - обычно / в основном - не нуждается в них.

Но для вашей конкретной проблемы («очень сложные запросы» и т. Д.) Это, возможно, неплохая идея. В зависимости от вашей версии базы данных Oracle, существуют глобальные временные таблицы (и - в самых последних версиях частные те). Как они работают? Вы создаете их один раз и используете много раз, что означает, что вы НЕ должны создавать их динамически. Данные, хранящиеся внутри, видны только вам, хотя многие пользователи могут использовать их одновременно. Кроме того, данные хранятся в течение всего сеанса (если вы решили создать их с опцией on commit preserve rows) или во время транзакции (on commit delete rows).

Например:

SQL> create global temporary table gtt_test
  2    (id     number,
  3     name   varchar2(20))
  4  on commit delete rows;

Table created.

SQL>

Вы можете индексировать их:

SQL> create index i1_gtt on gtt_test (id);

Index created.

SQL>

и делать все, что угодно. Как только ваша сессия (или транзакция) закончится, пух! они пусты, а данные не хранятся постоянно. Когда завтра тебе придется делать ту же самую работу, стол все еще здесь и ждет тебя. Нет динамический создание / удаление / создание / удаление (или все, что, как вы думали, следует делать).

Итак: создайте его один раз, используйте его в любое время.


Если должно быть динамическим, остерегайтесь этого:

SQL> declare
  2    l_cnt number;
  3  begin
  4    -- check whether table already exists
  5    select count(*)
  6      into l_Cnt
  7      from user_tables
  8      where table_name = 'TEST';
  9
 10    -- yes, it exists - drop it first
 11    if l_cnt = 1 then
 12       execute immediate 'drop table test';
 13    end if;
 14    -- now create it
 15    execute immediate 'create table test (id number, name varchar2(20))';
 16
 17    -- insert some rows
 18    insert into test (id, name) values (1, 'Littlefoot');
 19  end;
 20  /
  insert into test (id, name) values (1, 'Littlefoot');
              *
ERROR at line 18:
ORA-06550: line 18, column 15:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 18, column 3:
PL/SQL: SQL Statement ignored


SQL>

Хотя я сначала проверяю, существует ли таблица (чтобы я сначала ее отбросил, а затем заново создал)это), весь блок PL / SQL потерпел неудачу, потому что я пытаюсь использовать таблицу, которая еще не существует (во время компиляции).

Итак, если бы я хотел использовать эту testтаблица, любая операция - в том же блоке PL / SQL - также должна стать динамичной, и это ужасно : писать некрасиво, сложно отлаживать, остерегаться проблем с одинарными кавычками ... вы бы действительно хотелиИзбегайте этого.


Еще раз: я бы посоветовал вам не делать этого динамически.

...