Why temporary table is not allowed in stored procedure in Firebird?

Firebird doesn't allow you to use DDL inside stored procedures, so CREATE statements are disallowed in PSQL. As indicated in the answer by lad2025 you can work around this limitation by using EXECUTE STATEMENT.

However, the idea behind a global temporary table is that you create it once, and they continue to exist so they can be used later. The data is only visible to the connection that created the data, and the data is deleted after transaction commit (ON COMMIT DELETE ROWS) or connection close (ON COMMIT PRESERVE ROWS) depending on the type of global temporary table.

From the Firebird 3.0 Language Reference:

Global temporary tables have persistent metadata, but their contents are transaction-bound (the default) or connection-bound. Every transaction or connection has its own private instance of a GTT, isolated from all the others. Instances are only created if and when the GTT is referenced. They are destroyed when the transaction ends or on disconnection.

So instead of trying to create the global temporary table inside your stored procedure, create it first, then create your stored procedure that uses the already defined GTT.


From GTT documentation:

CREATE GLOBAL TEMPORARY TABLE

is a regular DDL statement that is processed by the engine the same way as a CREATE TABLE statement is processed. Accordingly, it not possible to create or drop a GTT within a stored procedure or trigger.

You can use Dynamic-SQL and wrap your code with EXECUTE STATEMENT as workaround:

SET TERM ^ ;

CREATE PROCEDURE initNATIONALHEALTHFUNDS
AS BEGIN

EXECUTE STATEMENT
  'CREATE GLOBAL TEMPORARY TABLE temp_FUNDS 
  (
    NATIONALHEALTHFUNDID Integer NOT NULL,
    NAME Varchar(128) NOT NULL,
    CODE Integer NOT NULL
  )
  ON COMMIT PRESERVE ROWS;
  commit;';

 ...

END^