Создание временной таблицы Oracle с той же структурой таблицы, что и у существующей таблицы - PullRequest
3 голосов
/ 23 марта 2019

Как создать глобальную временную таблицу с такой же структурой таблицы, как у существующей таблицы?

Я знаю, что эта концепция доступна на сервере SQL, например "select * into # temp123 from abc". Но я хочу сделать то же самое в Oracle.

Ответы [ 3 ]

4 голосов
/ 23 марта 2019
Create global temporary table mytemp 
as 
select * from myTable
where 1=2
2 голосов
/ 24 марта 2019

В синтаксисе SQL Server префикс «#» (хеш) в имени таблицы #temp123 означает - создать временную таблицу, доступную только через текущий сеанс («##» означает «Глобальный»).

Для достижения того же самого в Oracle вы можете использовать частные временные таблицы :

SQL> show parameter private_temp_table            

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
private_temp_table_prefix            string      ORA$PTT_

create table mytab as 
    select 1 id, cast ('aaa' as varchar2 (32)) name from dual
;

create private temporary table ora$ptt_mytab on commit preserve definition as
    select * from mytab where 1=0
;
Private TEMPORARY created.

После этого вы можете использовать эти таблицы в блоках SQL и PL / SQL:

declare
    r mytab%rowtype;
begin 
    insert into ora$ptt_mytab values (2, 'bbb');
    select id + 1, name||'x' into r from ora$ptt_mytab where rownum = 1;
    insert into ora$ptt_mytab values r;
end;
/
select * from mytab
union all
select * from ora$ptt_mytab;

        ID NAME                            
---------- --------------------------------
         1 aaa                             
         2 bbb                             
         3 bbbx                            

Некоторые важные ограничения для частных временных таблиц:

  • Имя всегда должно начинаться с префикса, определенного в параметре PRIVATE_TEMP_TABLE_PREFIX.По умолчанию ORA$PTT_.

  • Нельзя ссылаться на PTT в статических операторах именованных блоков PL / SQL, например пакетов, функций или триггеров.

  • Атрибут %ROWTYPE не применим к этому типу таблицы.

  • Невозможно определить столбец со значениями по умолчанию.

2 голосов
/ 24 марта 2019

Глобальные временные таблицы в Oracle сильно отличаются от временных таблиц в SQL Server. Они являются постоянными структурами данных , это просто данные в них, которые являются временными (ограничены сеансом или транзакцией, в зависимости от того, как определена таблица).

Следовательно, правильный способ использования глобальных временных таблиц сильно отличается от того, как мы используем временные таблицы в SQL Server. Оператор CREATE GLOBAL TEMPORARY TABLE является одноразовым упражнением (как и любая другая таблица). Удаление и воссоздание таблиц на лету - плохая практика в Oracle, которая не мешает людям, желающим это сделать .

Учитывая, что создание глобальной временной таблицы должно быть одноразовым упражнением, использование синтаксиса CREATE TABLE ... AS SELECT не дает никаких реальных преимуществ. Оператор должен быть явно определен, а скрипт должен храниться в системе контроля версий, как и любой другой DDL.


Вы отметили свой вопрос [oracle18c]. Если вы действительно используете Oracle 18c, у вас есть новая открытая функция, частные временные таблицы, которые ближе к временным таблицам SQL Server. Это таблицы, которые действительно находятся в памяти и автоматически удаляются в конце транзакции или сеанса (снова в соответствии с определением). Они описаны в документации Oracle , но вот заголовки.

Создание личных данных временных таблиц с подмножеством данных из постоянной таблицы T23:

create table t23  (
    id number primary key
    , txt varchar2(24)
    );

insert into t23 
select 10, 'BLAH' from dual union all 
select 20, 'MEH' from dual union all 
select 140, 'HO HUM' from dual
/


create private temporary table ORA$PTT_t23 
on commit preserve definition
as 
select * from t23
where id > 100;

Префикс ORA$PTT является обязательным (хотя его можно изменить, установив параметр init.ora PRIVATE_TEMP_TABLE_PREFIX, но зачем беспокоиться?

Там после того, как мы можем выполнить любой обычный DML для таблицы:

select * from ORA$PTT_t23;

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

declare 
    rec t23%rowtype;
begin
    select * 
    into rec
    from ORA$PTT_t23';
    dbms_output.put_line('id = ' || rec.id);
end;
/

ORA-06550: строка 6, столбец 10: PL / SQL: ORA-00942: таблица или представление не существует

Любая ссылка на частную временную таблицу в PL / SQL должна выполняться с помощью динамического SQL:

declare 
    n pls_integer;
begin
    execute immediate 'select id from ORA$PTT_t23' into n;
    dbms_output.put_line('id = ' || n);
end;
/

В основном это ограничивает их использование сценариями SQL * Plus (или sqlcl , которые выполняют серию операторов SQL). Так что, если у вас есть сценарий использования, который подходит для этого, вы должны проверить закрытые временные Таблицы. Однако, пожалуйста, учтите, что Oracle отличается от SQL Server во многих аспектах, не в последнюю очередь, с его многовариантной моделью согласованности: считыватели не блокируют средства записи . Следовательно, в Oracle гораздо меньше потребности во временных таблицах .

...