从 C 获取以行作为负载的 Postgres 通知

From C, get Postgres notification with row as payload

我正在尝试创建一个 postgres 函数,它向我的 C 代码发送通知,其中有效负载字符串是 table.

中一行的当前值

C端没问题。我有这样的东西:

// postgres setup ...
PGnotify *notify = PQnotifies(conn)
printf("Notification: '%s'\n", notify->extra); 

我希望它打印如下内容:Notification: MyTable{"ID":123,"Value":9,"Status":false}

在 Postgres 方面,我可以获得特定行作为 JSON 和

select row_to_json(row) 
from (
    SELECT * FROM "MyTable" WHERE "MyTable"."ID"=123
) row;

但我无法弄清楚如何在函数内执行此操作并将 select 的 json 结果保存到局部变量。我希望以下内容能够工作...

do language plpgsql $$ 
begin  
  myjson := (select row_to_json(row)  from (SELECT * FROM "MyTable" WHERE "MyTable"."ID"=123) row);
  -- myrow := ... somehow convert myjson to text ...
  -- pg_notify('mychannel', mytable || myrow);
end; 
$$;

...但我收到错误 "myjson is not a known variable"。我的 postgres fu 很弱,所以我确定这是一个简单的语法错误,但我无法弄清楚。我试过 'select into' 但也无法正常工作。

此外,您可以从注释行中看出我的意图是以某种方式将 json 转换为文本,但我不确定如何实现。

感谢任何帮助,谢谢!

显然我需要在它自己的块中声明变量。我猜它自己处理文本转换。此外,我必须将 perform 添加到 notify 命令,以使其不抱怨未使用的结果。这就是我最终得到的:

do language plpgsql $$ 
declare 
  mytable := "MyTable"
  myjson text;
begin  
  myjson := (select row_to_json(row)  from (SELECT * FROM "MyTable" WHERE "MyTable"."ID"=123) row);
  perform pg_notify('mychannel', mytable||myjson);
end; 
$$;

为了在查询中使用变量 mytable,我最终查看了 Executing Dynamic Commands 上的 postgres 文档并发现我需要这样做:

do language plpgsql $$ 
declare 
  mytable := "MyTable"
  myjson text;
begin  
  EXECUTE 
    format('(select row_to_json(row)  from (SELECT * FROM %I WHERE %I."ID"=101) row);', mytable, mytable)
    INTO myjson;
  perform pg_notify('mychannel', mytable||myjson);
end; 
$$;