INSERT 上的 PSQL 触发器和函数对错误
PSQL trigger and function pair bug on INSERT
我有一个 table (time TIMESTAMP PRIMARY KEY, pressure REAL NOT NULL
)。我需要开发一个 trigger/function 对来执行此操作:如果插入新条目,则根据时间戳更新现有条目或插入新条目。
触发代码:
CREATE TRIGGER trigger_insert
BEFORE INSERT ON mytable
FOR EACH ROW
EXECUTE PROCEDURE func_insert();
函数方法:
create or replace function func_insert()
returns trigger
language plpgsql
as
$$
DECLARE
time_exists TIMESTAMP;
BEGIN
IF pg_trigger_depth() <> 1 THEN
RETURN NEW;
END IF;
SELECT time INTO time_exists FROM mytable WHERE time = NEW.time;
IF NOT FOUND THEN
INSERT INTO mytable VALUES(NEW.*);
ELSE
UPDATE mytable SET pressure = NEW.pressure WHERE time = NEW.time;
END IF;
RETURN NEW;
END;
$$;
讨论:
没有IF pg_trigger_depth() <> 1 THEN
条件,脚本导致深度触发溢出异常
问题是我在将第一个(原文如此!)条目插入空(原文如此!)时出现错误 table:
psycopg2.errors.UniqueViolation: 重复键值违反唯一约束“mytable_pkey”
详细信息:密钥(“时间”)=(2019-06-01 00:00:00)已经存在。
谢谢。
如果要插入该行,只需 return new
而不是再次尝试 re-insert 它。
如果要更新该行,请不要return new
否则它会被插入...
也就是说,执行更新插入是最干净的解决方案
INSERT INTO myTable (time, pressure) VALUES (..., ...)
ON CONFLICT (time)
DO UPDATE SET pressure = EXCLUDED.pressure;
我有一个 table (time TIMESTAMP PRIMARY KEY, pressure REAL NOT NULL
)。我需要开发一个 trigger/function 对来执行此操作:如果插入新条目,则根据时间戳更新现有条目或插入新条目。
触发代码:
CREATE TRIGGER trigger_insert
BEFORE INSERT ON mytable
FOR EACH ROW
EXECUTE PROCEDURE func_insert();
函数方法:
create or replace function func_insert()
returns trigger
language plpgsql
as
$$
DECLARE
time_exists TIMESTAMP;
BEGIN
IF pg_trigger_depth() <> 1 THEN
RETURN NEW;
END IF;
SELECT time INTO time_exists FROM mytable WHERE time = NEW.time;
IF NOT FOUND THEN
INSERT INTO mytable VALUES(NEW.*);
ELSE
UPDATE mytable SET pressure = NEW.pressure WHERE time = NEW.time;
END IF;
RETURN NEW;
END;
$$;
讨论:
没有
IF pg_trigger_depth() <> 1 THEN
条件,脚本导致深度触发溢出异常问题是我在将第一个(原文如此!)条目插入空(原文如此!)时出现错误 table:
psycopg2.errors.UniqueViolation: 重复键值违反唯一约束“mytable_pkey” 详细信息:密钥(“时间”)=(2019-06-01 00:00:00)已经存在。
谢谢。
如果要插入该行,只需 return new
而不是再次尝试 re-insert 它。
如果要更新该行,请不要return new
否则它会被插入...
也就是说,执行更新插入是最干净的解决方案
INSERT INTO myTable (time, pressure) VALUES (..., ...)
ON CONFLICT (time)
DO UPDATE SET pressure = EXCLUDED.pressure;