他の人が述べたように、一時テーブルは明示的に削除するかセッションが終了するまで存続します。
テーブルが既に存在するためにストアド プロシージャが失敗した場合、SPL は例外を生成します。ON EXCEPTION 句を追加することで例外に対処できますが、SPL のよりバロックな部分の 1 つであるストアド プロシージャ言語に入る必要があります。
これは、ストアド プロシージャを少し変更したバージョンです。ゼロ除算の例外 (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 を実行し、テーブルを作成した後、ゼロ除算に違反したことを示しています。ただし、2 回目は、一時テーブルが既に存在していたために 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 Guide to SQL: Syntax マニュアルの第 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;