【发布时间】:2015-04-10 19:04:50
【问题描述】:
在 PostgreSQL 中,我想创建一个安全包装机制,如果发生异常,它会返回空结果。考虑以下几点:
SELECT * FROM myschema.mytable;
我可以在客户端应用程序中进行安全包装:
try {
result = execute_query('SELECT value FROM myschema.mytable').fetchall();
}
catch(pg_exception) {
result = []
}
但是我可以直接在 SQL 中做这样的事情吗?我想让下面的代码工作,但它似乎应该被放入 DO $$ ... $$ 块中,我在这里迷路了。
BEGIN
SELECT * FROM myschema.mytable;
EXCEPTION WHEN others THEN
SELECT unnest(ARRAY[]::TEXT[])
END
【问题讨论】:
-
DO无法返回任何内容。您必须为此使用存储过程(使用语言plpgsql- 用于异常处理)。 -- 还有没有返回行不等于返回单行,里面有一个空数组(即在js中,这意味着[] != [{col1:[]}])。 -
@posz 抱歉,我在示例中添加了
unnest以产生所需的行为(不知道如何更优雅地执行此操作)。无论如何,每次执行带有异常处理的查询时,我是否必须声明过程?没有其他选择吗? -
所以您想防御任何和所有异常,或者您只是担心该表可能不存在?你想返回什么?来自单个列
value的单个值?还是一组行?这是针对一个硬编码表名还是针对各种可能的表名? -
@Tregoreg 不,如果您想仅对简单查询进行异常处理,这通常由客户端完成,而不是服务器。
plpgsql的异常处理主要针对存储的“逻辑”。但是你害怕什么类型的异常?也许,还有其他选择。 -
@posz 实际上,在我的具体情况下,我非常关心竞争条件。我正在使用
SELECT ('myschema','mytable') IN (SELECT table_schema,table_name FROM information_schema.tables);检查表是否存在,如果存在,我将选择它的行。但是经常发生在执行第二个查询之前表不存在的情况(即,成语“如果表存在,则选择其内容”不起作用)。这就是为什么我希望在发生异常时简单地返回空结果。
标签: sql postgresql exception-handling plpgsql dynamic-sql