Все вне фигурных скобок расположено, таким образом, замечательно расположить Ваши объекты, если Вы не используете их. Это так, потому что, если Вы сделали, чтобы SqlDataAdapter возразил и Вы используете его только однажды в жизненном цикле приложения, и Вы заполняете всего один набор данных, и Вам больше не нужен он, можно использовать код:
using(SqlDataAdapter adapter_object = new SqlDataAdapter(sql_command_parameter))
{
// do stuff
} // here adapter_object is disposed automatically
I finally used a variation of Jonathan's and RET's solution:
CREATE PROCEDURE foo ()
ON EXCEPTION IN (-206)
END EXCEPTION WITH RESUME;
DROP TABLE tempTable;
SELECT * FROM fooBar INTO TEMP tempTable;
-- do something with tempTable here
DROP TABLE tempTable;
END PROCEDURE;
Согласно документации , временные таблицы удаляются после завершения сеанса.
Да, временная таблица все еще будет существовать. Временные таблицы по определению имеют время жизни сеанса, в котором они были созданы, если они явно не удалены.
Временную таблицу может видеть только сеанс, который ее создал, и нет никаких препятствий для параллельного выполнения одной и той же процедуры несколькими пользователей. Ответ Адама на проверку существования временной таблицы вернет ненулевой результат, если какой-либо пользователь запускает процедуру. Вам необходимо проверить, что сеанс, которому принадлежит временная таблица, также является текущим сеансом. Учитывая, что этот вопрос находится в рамках хранимой процедуры, было бы проще добавить явный DROP,
SELECT count(*)
INTO w_count
FROM sysmaster:systabnames s,sysmaster:systabinfo i
WHERE i.ti_partnum = s.partnum
AND sysmaster:BITVAL(i.ti_flags,'0x0020') = 1
AND s.tabname = 'tempTable' ;
Если w_count равно 1, удалить таблицу перед SELECT ... INTO. То же самое с DROP TABLE.
Как утверждали другие, временные таблицы существуют до тех пор, пока вы не удалите их явно или не завершится сеанс .
Если хранимая процедура завершается неудачно из-за того, что таблица уже существует, 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 ограничивает обработку исключений оператором захвата. Без BEGIN / END обработка исключений охватывает всю процедуру, также реагируя на ошибку деления на ноль (и, следовательно, позволяет DROP TABLE работать, и процедура, похоже, выполняется успешно).
Обратите внимание, что temptable все еще существует на этом этапе:
+ 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 к операторам CREATE и DROP были добавлены условия IF EXISTS и IF NOT EXISTS. Таким образом, вы можете использовать модифицированный оператор 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;