【问题标题】:Continue loop when dblink SQL statement timeout occursdblink SQL 语句超时时继续循环
【发布时间】:2023-01-20 01:28:48
【问题描述】:

我正在编写一个使用 dblink 循环遍历多个远程数据库的过程,我想包含语句超时以防止查询挂起时间过长。但是,如果发生此类超时,整个过程将失败并出现:

ERROR: canceling statement due to statement timeout
SQL state: 57014
Context: while executing query on dblink connection named xxx

我想忽略它并继续循环。

通常这样的代码只允许跳过异常抛出通知,但不允许取消 dblink 查询。

do $$
declare
exceptionMsg text;
BEGIN
 select * from foo;
 exception when others then get stacked diagnostics exceptionMsg = message_text;
     raise notice ' ******EXCEPTION*******
     %
     **************', exceptionMsg;  
END;
 $$

在这里包含整个过程太长了,但它会遍历数据库并在每个数据库之后提交结果。一切正常,除了处理这些超时,部分代码如下所示:

for rec in (select dbc.db_name, dbc.con_string || ' options = ''-c statement_timeout='||_queryTimeout*1000||''' ' as con_string
            from db_connections dbc
            )
LOOP

PERFORM dblink_connect(rec.db_name, rec.con_string); 

raise notice '% start',  rec.db_name ;

BEGIN
    insert into results_tbl (db_name, value, query_text)
        select rec.db_name, value, _queryText
        from dblink(rec.db_name, format($query$
            select json_agg(x.*)::text from (%1$s)x -- it's like this to avoid declaring every column used in the query
            $query$, _queryText 
        ) ) r (value text);

exception when others then get stacked diagnostics exceptionMsg = message_text;
     raise notice ' ******EXCEPTION*******
     %
     **************', exceptionMsg;  
END;

PERFORM dblink_disconnect( rec.db_name );
COMMIT;

raise notice '% done',  rec.db_name ;
END LOOP;

【问题讨论】:

    标签: sql postgresql loops dblink


    【解决方案1】:

    As documented,

    特殊条件名称 OTHERS 匹配除 QUERY_CANCELEDASSERT_FAILURE 之外的所有错误类型。

    所以你需要明确地捕获QUERY_CANCELED

    捕获 OTHERS 是一种糟糕的风格。只捕获您期望的异常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-23
      • 2016-10-07
      • 1970-01-01
      • 1970-01-01
      • 2010-11-01
      • 2017-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多