Come altri hanno dichiarato, le tabelle temporanee durano fino a quando non le rilasciate esplicitamente o la sessione termina.
Se la stored procedure non riesce perché la tabella esiste già, SPL genera un'eccezione. È possibile gestire eccezioni aggiungendo una clausola ON EXCEPTION, ma si entra in una delle parti più barocche di SPL, Stored Procedure Language.
Ecco una versione leggermente modificata della stored procedure - quella che genera una divisione per un'eccezione zero (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.
Questo dimostra che la prima volta attraverso il codice eseguito la SELECT, creando il tavolo, e poi ha eseguito fallo della divisione per zero. La seconda volta, tuttavia, la SELECT non è riuscita perché la tabella temporanea esisteva già, quindi il diverso messaggio di errore.
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;
Il blocco BEGIN/END limita la gestione delle eccezioni all'istruzione intrappolata. Senza BEGIN/END, la gestione delle eccezioni copre l'intera procedura, reagendo anche all'errore di divisione per zero (e quindi lasciando funzionare DROP TABLE e la procedura sembra funzionare correttamente).
noti che temptable ancora presente in tale punto:
+ 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.
Ciò dimostra che il procedimento non riesce perché la tabella temporanea è presente.
È possibile limitare il blocco ON eccezione a codici di errore selezionati (-958 sembra plausibile per questo) da:
ON EXCEPTION IN (-958) ...
consultare la Guida Informix IBM per SQL: sintassi manuale, capitolo 3 Bilancio SPL ' .
Nota che Informix 11.70 ha aggiunto il 'IF EXISTS' e 'SE NON ESISTE' clausole di creare e Istruzioni DROP. Così, è possibile utilizzare la modifica DROP TABLE dichiarazione:
DROP TABLE IF EXISTS tempTable;
Così, con Informix 11.70 o poi, il modo più semplice di scrivere la procedura è:
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;
Si potrebbe anche usare questo, ma poi si ottenere la definizione precedente della procedura, qualunque essa fosse, e potrebbe non essere quello che ti aspettavi.
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;
Quello che hai qui - rilascia la tabella ma ignora l'errore se non esiste - è un buon modo per andare. In circostanze normali, manca la tabella temporanea prima dell'esecuzione e dopo il completamento. Sarebbe possibile modificare l'ambito dell'eccezione, ma dovrebbe funzionare correttamente. –
Nota che Informix moderna supporta le clausole IF EXISTS e IF NOT EXISTS in istruzioni come DROP TABLE. Quindi, in questi giorni, potresti scrivere: 'DROP TABLE IF EXISTS tempTable;' che lascerà cadere la tabella se è presente (e tu hai il permesso, ecc.) E non fare nulla se la tabella non esiste. –