2014-11-23 2 views
2

я уже попытался это:Как создать временную таблицу как копию другой таблицы в Oracle?

CREATE GLOBAL TEMPORARY TABLE tempTable AS 
SELECT * FROM realTable; 

Но TempTable имеет только структуру realTable, но не сами элементы.

+0

Это * должно * заполнить стол, но вы всегда можете сделать вставку впоследствии. –

+0

Как я могу заполнить его после создания? –

+1

'insert into tempTable select * from realtable'. Конечно, списки столбцов предпочтительнее, но это должно сработать. –

ответ

12

«Но тогда tempTable имеет только структуру realTable, но не самих элементов ».

Что делает временную временную таблицу временным, так это то, что данные являются временными. Во-первых, данные видны только в сеансе, который вставляет его; любая другая сессия увидит пустую таблицу. Во-вторых, данные могут сохраняться как для транзакции, так и для сеанса, в зависимости от предложения ON COMMIT; по умолчанию ВКЛЮЧЕН УДАЛ. Find out more.

Теперь дело в том, что в заявлении DDL в Oracle возникают две коммиты: одна до и одна после соответствующего утверждения. Таким образом, заявление DDL представляет собой полную, дискретную транзакцию. Следовательно, это ...

CREATE GLOBAL TEMPORARY TABLE tempTable AS 
SELECT * FROM realTable; 

... это сделка, и, как это не указывает ON COMMIT положение, оно будет применяться по умолчанию, который является удаление строк. Таким образом, пустая таблица - это ожидаемое поведение.

Решение простое: указать ON COMMIT заявление с сохранением уровня сеанса:

SQL> select count(*) from t23; 

    COUNT(*) 
---------- 
     11 

SQL> create global temporary table gtt23 
    2 as select * from t23 
    3/

Table created. 

SQL> select count(*) from gtt23; 

    COUNT(*) 
---------- 
     0 

SQL> drop table gtt23; 

Table dropped. 

SQL> create global temporary table gtt23 
    2 on commit preserve rows 
    3 as select * from t23 
    4/

Table created. 

SQL> select count(*) from gtt23; 

    COUNT(*) 
---------- 
     11 

SQL> 

Вообще, я считаю, что политика CREATE GLOBAL TEMPORARY TABLE с помощью SELECT * FROM указывает на непонимание конструкции. GTT в Oracle: постоянные структуры данных; только записи являются временными. Они не являются одноразовыми объектами, такими как временные таблицы в T-SQL. Если это то, чего вы хотите, скорее всего, вы должны использовать коллекцию PL/SQL. Find out more.

+1

+ 1. , , Очень приятное объяснение. Я считаю поведение по умолчанию противоречивым, но по крайней мере теперь это имеет смысл. –

2

Глобальные временные таблицы могут обладать областью уровня транзакции или областью уровня сеанса. По умолчанию используется область транзакций на уровне транзакции, что означает, что данные исчезают после завершения транзакции. Если вы создаете глобальную временную таблицу CREATE TABLE AS SELECT, данные будут вставлены, но, поскольку CREATE - это DDL, данные будут удалены, как только инструкция завершится.

Одним из вариантов было бы создать структуру с помощью запроса, который не возвращает никаких данных

CREATE GLOBAL TEMPORARY TABLE tempTable AS 
    SELECT * 
    FROM realTable 
    WHERE 1=0; 

затем вставить данные

INSERT INTO tempTable 
    SELECT * 
    FROM realTable; 

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

Смежные вопросы