问题:
我已经设置了一个 PostgreSQL 函数和触发器,以便在
INSERT
表上有 UPDATE
、DELETE
或 RiderDataPosition
操作时发送通知。然而,尽管我做出了努力,但我没有收到预期的任何通知。我正在寻求有关解决此问题的指导。我的最终结果是,当“RiderDataPosition”表中的某些内容发生变化时,我希望收到通知。
更新
向数据库发送查询
NOTIFY RiderPositionUpdate
时,我的测试应用程序收到响应。这意味着触发器出了问题!
问题描述:
我有一个在 Docker 容器中运行的 PostgreSQL 数据库,并且我使用的是最新版本。目标是每当
RiderPositionUpdate
表发生更改时向 RiderDataPosition
通道发送通知。这是我到目前为止所做的:
通知功能:
我创建了一个通知功能,如下所示:
CREATE OR REPLACE FUNCTION "TrackSolutionsCore".notify_rider_position_change()
RETURNS TRIGGER AS $$
BEGIN
IF TG_OP = 'INSERT' THEN
PERFORM pg_notify('RiderPositionUpdate', json_build_object('operation', 'insert', 'record_id', NEW."TransponderId")::text);
RAISE NOTICE 'Inserted record with TransponderId %', NEW."TransponderId";
RETURN NEW;
ELSIF TG_OP = 'UPDATE' THEN
PERFORM pg_notify('RiderPositionUpdate', json_build_object('operation', 'update', 'record_id', NEW."TransponderId")::text);
RAISE NOTICE 'Updated record with TransponderId %', NEW."TransponderId";
RETURN NEW;
ELSIF TG_OP = 'DELETE' THEN
PERFORM pg_notify('RiderPositionUpdate', json_build_object('operation', 'delete', 'record_id', OLD."TransponderId")::text);
RAISE NOTICE 'Deleted record with TransponderId %', OLD."TransponderId";
RETURN OLD;
END IF;
END;
$$ LANGUAGE plpgsql;
触发器:
我在
AFTER INSERT
表上为 AFTER UPDATE
、AFTER DELETE
和 RiderDataPosition
操作创建了触发器。以下是其中一个触发器的示例:
CREATE TRIGGER rider_data_position_insert_trigger
AFTER INSERT ON "TrackSolutionsCore"."RiderDataPosition"
FOR EACH ROW
EXECUTE FUNCTION "TrackSolutionsCore".notify_rider_position_change();
表结构:
RiderDataPosition
表具有以下结构:
CREATE TABLE "RiderDataPosition"
(
"TransponderId" integer generated by default as identity
constraint "PK_RiderDataPosition"
primary key,
-- Other columns...
);
面临的问题:
尽管设置了这些触发器和通知功能,但当我对
RiderPositionUpdate
表执行 CRUD 操作时,我在 RiderDataPosition
通道上没有收到任何通知。我尝试使用 NotificationEventHandler
通过 C# 应用程序接收这些通知,并通过在控制台中执行 LISTEN "RiderPositionUpdate"
直接通过 DataGrip 接收这些通知,但这两种方法都不会产生结果。
环境:
测试申请
using Npgsql;
var conn = new NpgsqlConnection("connectionString");
conn.Open();
conn.Notification += (o, e) => Console.WriteLine("Received notification");
using (var cmd = new NpgsqlCommand("LISTEN RiderPositionUpdate", conn)) {
cmd.ExecuteNonQuery();
}
while (true) {
conn.Wait(); // Thread will block here
}
向表中插入新记录后 DataGrip 中的输出
问题:
任何有关如何诊断和解决此问题的见解或指导将不胜感激。谢谢!
您的大小写不匹配。如果您的频道名称包含真正的大写字母,则该名称必须在 LISTEN 命令中用双引号引起来。您的 NOTIFY 命令可与您的 LISTEN 配合使用,因为它会像 LISTEN 一样对通道名称进行大小写折叠,而 pg_notify 不会对其第一个参数进行大小写字段处理,因此它不起作用。
但更好的是,更改您的频道名称,使其中没有大写字母。