Как уже говорилось, временные таблицы сохраняются до тех пор, пока вы не удалите их явно или сеанс не завершится.
Если хранимая процедура завершается ошибкой из-за того, что таблица уже существует, SPL генерирует исключение.
Вы можете иметь дело с исключениями, добавив предложение ON EXCEPTION - но вы вводите одну из более барочных частей SPL, язык хранимых процедур.
Вот слегка измененная версия вашей хранимой процедуры - та, которая генерирует исключение деления на ноль (SQL -1202):
CREATE PROCEDURE foo ()
define i integer;
SELECT * FROM 'informix'.systables INTO TEMP tempTable;
-- do something with tempTable here
let i = 1 / 0;
DROP TABLE tempTable;
END PROCEDURE;
execute procedure foo();
SQL -1202: An attempt was made to divide by zero.
execute procedure foo();
SQL -958: Temp table temptable already exists in session.
Это показывает, что в первый раз через код выполнялся SELECT, создавая таблицу, а затем выполнялся фол деления на ноль. Во второй раз, однако, произошел сбой SELECT, поскольку временная таблица уже существует, отсюда и другое сообщение об ошибке.
drop procedure foo;
CREATE PROCEDURE foo()
define i integer;
BEGIN
ON EXCEPTION
DROP TABLE tempTable;
SELECT * FROM 'informix'.systables INTO TEMP tempTable;
END EXCEPTION WITH RESUME;
SELECT * FROM 'informix'.systables INTO TEMP tempTable;
END;
-- do something with tempTable here
let i = 1 / 0;
DROP TABLE tempTable;
END PROCEDURE;
Блок BEGIN / END ограничивает обработку исключений оператором trapped. Без BEGIN / END обработка исключений охватывает всю процедуру, также реагируя на ошибку деления на ноль (и, следовательно, позволяя DROP TABLE работать и процедура, кажется, выполняется успешно).
Обратите внимание, что в этот момент все еще существует искушаемое:
+ execute procedure foo();
SQL -1202: An attempt was made to divide by zero.
+ execute procedure foo();
SQL -1202: An attempt was made to divide by zero.
Это показывает, что процедура больше не завершается сбоем из-за наличия временной таблицы.
Вы можете ограничить блок ON EXCEPTION выбранными кодами ошибок (-958 кажется вероятным для этого) с помощью:
ON EXCEPTION IN (-958) ...
См. Руководство IBM Informix по SQL: руководство по синтаксису, глава 3 «Операторы SPL».
Обратите внимание, что Informix 11.70 добавил операторы 'IF EXISTS' и 'IF NOT EXISTS' в операторы CREATE и DROP. Таким образом, вы можете использовать модифицированный оператор DROP TABLE :
DROP TABLE IF EXISTS tempTable;
Таким образом, в Informix 11.70 или более поздней версии проще всего написать процедуру:
DROP PROCEDURE IF EXISTS foo;
CREATE PROCEDURE foo()
define i integer;
DROP TABLE IF EXISTS tempTable;
SELECT * FROM 'informix'.systables INTO TEMP tempTable;
-- do something with tempTable here
let i = 1 / 0;
DROP TABLE tempTable; -- Still a good idea
END PROCEDURE;
Вы также можете использовать это, но затем вы получите предыдущее определение процедуры, какой бы она ни была, и это может быть не то, что вы ожидали.
CREATE PROCEDURE IF NOT EXISTS foo()
define i integer;
DROP TABLE IF EXISTS tempTable;
SELECT * FROM 'informix'.systables INTO TEMP tempTable;
-- do something with tempTable here
let i = 1 / 0;
DROP TABLE tempTable; -- Still a good idea
END PROCEDURE;