2015-11-29 2 views
0

Я хотел бы создать и заполнить временную таблицу с данными для его обработки внутри оператора цикла, как это:Почему блок PL/SQL не создает временную таблицу?

DECLARE 
    cnt NUMBER; 
BEGIN 


    SELECT COUNT(tname) INTO cnt from tab where tname = 'MY_TEMP'; 
    IF (cnt > 0) THEN 
    EXECUTE IMMEDIATE 'DROP TABLE MY_TEMP'; 
    END IF; 

    EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE MY_TEMP (G NVARCHAR2(128), F NVARCHAR2(128), V NVARCHAR2(128)) ON COMMIT DELETE ROWS'; 

    INSERT INTO MY_TEMP VALUES (N'G-value1', N'F-value1', N'V-value1'); 
    INSERT INTO MY_TEMP VALUES (N'G-value2', N'F-value2', N'V-value2'); 
    ... 

    FOR record IN (SELECT G,F,V FROM MY_TEMP) 
    LOOP 

    ... Do something sophisticated with record.G, record.F, record.V 
    END LOOP; 

    COMMIT; 
END; 

Когда я запускаю этот скрипт внутри PL-SQL Developer он говорит мне в первую ВСТАВКУ, что MY_TEMP стола или представление не существует, хотя мой EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE ...' выглядит, как представляется, без ошибок. Я проверил, нет таблицы MY_TEMP внутри списка таблиц после выполнения сценария

Когда я запускаю EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE ...', он работает нормально, а таблица MY_TEMP действительно создана. После этого все скрипты работают нормально.

Как использовать этот скрипт без ручной обработки таблицы MY_TEMP вручную?

+0

Здравствуйте, @DaveH. Я скорректировал свой пример кода. – user149691

+2

Это не то, как временные таблицы работают в Oracle. Создайте их ** один раз **, а затем используйте их в своей процедуре - как и в любой другой таблице. –

ответ

4

Как использовать этот сценарий, вручную precreating MY_TEMP таблицы?

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

Дело не в том, что ваш сценарий не в перспективе, но он не компилировать. Oracle не будет запускать ваш блок, если он не сможет скомпилировать его в первую очередь. В точке, где Oracle пытается скомпилировать ваш блок PL/SQL, таблица не существует. У вас есть ошибка компиляции, а не ошибка времени выполнения.

Я подозреваю, что вы более знакомы с временными таблицами в SQL Server и пытаетесь использовать временные таблицы в Oracle таким же образом. Если это так, то вам нужно знать, что существуют различия между временными таблицами в Oracle и SQL Server.

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

Я действительно не думаю, что вам нужно создать временную таблицу в своем блоке. Достаточно создать его заблаговременно.

0

Почему вы хотите сбросить и создать временную таблицу? Просто создайте его и используйте.

+0

Я просто хочу убедиться, что он удален, прежде чем я попытаюсь его создать. – user149691

0

Создание временной таблицы в Oracle не лучшая практика, вместо этого использовать PIVOT

0
The only way around for your problem is to make the whole INSERT INTO temp_table statements into EXECUTE IMMEDIATE in this way you can BYPASS the TABLE check during COMPILE Time first. 
But this way in my opinion is not good at all. There are some questions in my mind which has be answred before answering this question. 

1) Why Temp Table is created evertime and Dropped. 
We have option in GTT to keep or Remove Data after one Oracle Session. 
2) Is this script a one time job ? If Yes then we can go for once GTT creation and the rest script will work fine. 
0

Проблема не в вашей первой вставке. Это с компиляцией вашего блока. Таблица не существует, но вы ссылаетесь на нее. Попытайтесь создать его так, чтобы он был таким, каким он будет после завершения цветения. Теперь код, скорее всего, будет компилироваться, поскольку ссылка на таблицу существует при ее запуске.

Однако, у вас возникнут проблемы с падением, так как ваш код имеет блокировку общего доступа на столе, поэтому вам не разрешено его удалять.

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

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