rob*_*nwk 6 database stored-procedures temp-tables firebird-3.0
我试图在Firebird数据库中的存储过程中创建临时表.
我的存储过程列表:
SET TERM ^ ;
CREATE PROCEDURE initNATIONALHEALTHFUNDS
AS BEGIN
CREATE GLOBAL TEMPORARY TABLE temp_FUNDS
(
NATIONALHEALTHFUNDID Integer NOT NULL,
NAME Varchar(128) NOT NULL,
CODE Integer NOT NULL
)
ON COMMIT PRESERVE ROWS;
commit;
INSERT INTO tempFUNDS (NATIONALHEALTHFUNDID, CODE, NAME) VALUES ( 01 ,01 , 'Some Foundation');
MERGE INTO NATIONALHEALTHFUNDS AS target
USING tempFUNDS AS source
ON target.NATIONALHEALTHFUNDID = source.NATIONALHEALTHFUNDID
WHEN NOT MATCHED THEN
INSERT (NATIONALHEALTHFUNDID, CODE, NAME) VALUES (source.NATIONALHEALTHFUNDID, source.CODE, source.NAME);
drop TABLE tempFUNDS;
END^
SET TERM ; ^
Run Code Online (Sandbox Code Playgroud)
每次我尝试创建此过程时,我都会收到错误:
Engine Code : 335544569
Engine Message :
Dynamic SQL Error
SQL error code = -104
Token unknown - line 7, column 3
CREATE
Total execution time: 0.015s
Run Code Online (Sandbox Code Playgroud)
我做错了什么?Firebird 3.0 RC
提前谢谢罗伯特
Firebird不允许您在存储过程中使用DDL,因此CREATEPSQL中不允许使用语句。如lad2025的答案所示,您可以使用来解决此限制EXECUTE STATEMENT。
但是,全局临时表的想法是您只需创建一次,并且它们会继续存在,以便以后使用。数据仅对创建数据的连接可见,并且根据全局临时表的类型,在事务落实(ON COMMIT DELETE ROWS)或连接关闭(ON COMMIT PRESERVE ROWS)之后删除数据。
从语言参考更新:
全局临时表具有持久性元数据,但是其内容是受事务约束的(默认值)或受连接约束的。每个事务或连接都有其自己的GTT私有实例,与其他所有实例隔离。仅在引用GTT时以及在引用GTT时创建实例,并在事务结束或断开连接时销毁实例。
因此,与其尝试在存储过程中创建全局临时表,不如先创建它,然后创建使用已定义的GTT的存储过程。