首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将变量传递给函数时出错

将变量传递给函数时出错
EN

Database Administration用户
提问于 2021-03-10 09:26:21
回答 2查看 144关注 0票数 0

我在PostgreSQL 11.10中创建了一个函数来处理DDL更改,并将其应用到订阅服务器中。以下是功能:

代码语言:javascript
运行
复制
CREATE OR REPLACE FUNCTION public.intercept_ddl()
 RETURNS event_trigger
 LANGUAGE plpgsql
AS $function$
  declare _qry text;
BEGIN
  if (tg_tag='CREATE TABLE' or tg_tag='ALTER TABLE' or tg_tag='DROP TABLE') then
            SELECT current_query() into _qry;
            PERFORM pglogical.replicate_ddl_command('_qry', '{default}'), _qry;
                                                                               
 end if;
END;
$function$
;

当我尝试它时,它抛出了一个错误:

错误:" _qry“行1或附近的语法错误:选择pglogical.replicate_ddl_command('_qry','{default}') ^ QUERY:选择pglogical.replicate_ddl_command('_qry','{default}')上下文:在执行排队SQL语句时:执行_qry PL/pgSQL函数intercept_ddl()第6行

如何传递_qry变量以便我们可以使用它replicate_ddl_command()

按照Laurenz的指示修复单引号之后,我再次尝试使用以下命令:

代码语言:javascript
运行
复制
alter table test alter COLUMN description type text; 

并得到另一条错误消息:

错误:无法删除活动门户"pglogical“上下文:在执行排队的SQL语句期间: alter测试alter列描述类型text;SQL语句"SELECT pglogical.replicate_ddl_command( _qry,'{default}')”PL/pgSQL函数intercept_ddl()在执行时第7行

EN

回答 2

Database Administration用户

发布于 2021-03-10 22:59:40

除了按照Laurenz的指示修正单引号外,您可能还必须使用(默认的!)复制为命令'{ddl_sql}'设置replicate_ddl_command()。错误信息

无法删除活动门户"pglogical“

指示具有准备语句的打开门户,该语句将与DDL命令冲突。

代码语言:javascript
运行
复制
CREATE OR REPLACE FUNCTION public.intercept_ddl()
  RETURNS event_trigger
  LANGUAGE plpgsql AS
$func$
BEGIN
   PERFORM pglogical.replicate_ddl_command(current_query(), '{ddl_sql}');  -- !!
END
$func$;

您没有公开实际的事件触发器,但可能如下所示

代码语言:javascript
运行
复制
CREATE EVENT TRIGGER foo
ON ddl_command_start
WHEN TAG IN ('CREATE TABLE', 'ALTER TABLE', 'DROP TABLE')
EXECUTE FUNCTION public.intercept_ddl();

在触发器本身中筛选命令标记,从而避免了函数中这样做的需要。这是更有效的,因为函数的调用只适用于适用的标记开始。

引用逻辑手册

已有的三个复制集名为“default”、“default_insert_only”和“ddl_sql”。定义“ddl_sql”复制集是为了复制pglogical.replicate_ddl_command指定的模式更改。

和:

  • pglogical.replicate_ddl_command(command text, replication_sets text[])在本地执行,然后将指定的命令发送到复制队列,以便在订阅指定replication_sets.Parameters:之一的订阅服务器上执行。
    • 命令- DDL查询以执行
    • replication_sets -此命令应该与其关联的复制集数组默认为“{ddl_sql}”。
票数 1
EN

Database Administration用户

发布于 2021-03-10 09:35:47

单引号中使用_qry作为字符串常量,构成非法的SQL语句。此外,奇怪的附录, _qry是语法上的无稽之谈。

试一试

代码语言:javascript
运行
复制
PERFORM pglogical.replicate_ddl_command(_qry, '{default}');

然后,_qry将被识别为变量引用。

票数 0
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/286788

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档