我想通过psql在空数据库中加载一些SQL函数:
psql -d my_database -f fuctions.sql --set ON_ERROR_STOP=1
我使用
--set ON_ERROR_STOP=1
是因为我希望psql在脚本包含错误时失败。functions.sql
的内容是:CREATE or REPLACE FUNCTION test_function() RETURNS INT AS $$
SELECT id from test_table;
$$ LANGUAGE sql;
我的问题是,当加载函数时,PSQL检查是否存在“cc>”,并在这个错误中失败:
ERROR: relation "test_table" does not exist LINE 2: SELECT id from test_table;
但我不希望PSQL检查表是否存在,因为稍后我将创建这个表。
以下解决方法可以工作,但我不能使用它们:
忽略错误。如果脚本包含SQL语法错误,我希望PSQL退出一个错误。
使用plpgsql函数而不是sql。当然可以,但简单的sql函数通常是最好的选择。
先创建表。我的真实场景实际上比这个例子更复杂。
最佳答案
错误消息来自Postgres,而不是psql。
解决办法
如果您不能首先创建表(无论出于什么原因),您可以“假装它,直到您创建它”:创建一个具有匹配结构的临时表。您只需要匹配列名和类型。对于示例函数:
CREATE TEMP TABLE test_table (id int);
然后
CREATE FUNCTION
通过。不禁止以后删除表。Postgres不保存函数体中代码的依赖项。因此,一旦创建了函数,就可以删除表。如果在删除临时表后调用该函数,则会出现错误。稍后创建实际表后,该函数将正常工作。
在创建时禁用SQL函数解析?
据我所知,这是不可能的。也许Postgres有一个编译时选项来禁用它。The manual advises to use PL/PgSQL for cases like yours:
注意:SQL函数的整个主体在
执行。而SQL函数可以包含改变
系统目录(例如
CREATE TABLE
),这些命令的效果在分析
功能。因此,例如,
CREATE TABLE foo (...); INSERT INTO foo VALUES(...);
如果打包到单个SQL中,将无法按预期工作函数,因为在解析
foo
命令时还不存在。建议在这里使用PL/PgSQL而不是SQL函数
情况类型。
大胆强调我的。