我在这个简单的触发器中遇到了困难。我的目的是在插入新寄存器之前验证是否存在具有相同字段内容的寄存器“tag_id”。如果NEW tag_id与我的表“coordenadas”上的任何寄存器的tag_id相同,那么它会更新,如果没有,则会插入一个新的。当我尝试插入某事时,我收到错误:
ERROR: record "old" is not assigned yet
DETAIL: The tuple structure of a not-yet-assigned record is indeterminate.
CONTEXT: PL/pgSQL function verifica_coo() line 7 at IF
我有这张桌子:
CREATE TABLE public.coordenadas
(
id bigint NOT NULL,
pos_data timestamp without time zone,
pos_latitude double precision,
pos_longitude double precision,
tag_id bigint NOT NULL,
gado_id bigint NOT NULL,
CONSTRAINT coordenadas_pkey PRIMARY KEY (id),
CONSTRAINT coordenadas_gado_id_fkey FOREIGN KEY (gado_id)
REFERENCES public.gado (gado_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fkj14dwmpa6g037ardymqc2q4lj FOREIGN KEY (tag_id)
REFERENCES public.tag (tag_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fktawrw6tlliq4ace5p7io87c5p FOREIGN KEY (gado_id)
REFERENCES public.gado (gado_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
此触发器:
CREATE TRIGGER verifica_coo
BEFORE INSERT OR UPDATE ON coordenadas
FOR EACH ROW EXECUTE PROCEDURE verifica_coo();
此功能:
CREATE OR REPLACE FUNCTION public.verifica_coo()
RETURNS trigger AS $verifica_coo$
BEGIN
--
-- Verifica se é para inserir ou atualizar os dados na tabela.
--
IF (NEW.tag_id != OLD.tag_id ) THEN
INSERT INTO coordenadas (pos_data,pos_latitude,pos_longitude,tag_id,gado_id)
VALUES (NEW.pos_data,NEW.pos_latitude,NEW.pos_longitude,NEW.tag_id,NEW.gado_id);
ELSE
UPDATE coordenadas SET pos_data = NEW.pos_data, pos_latitude = NEW.pos_latitude, pos_longitude = NEW.pos_longitude WHERE tag_id = NEW.tag_id;
END IF;
RETURN NEW;
END;
$verifica_coo$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION public.verifica_coo()
OWNER TO postgres;
我的插入内容:
INSERT INTO coordenadas (pos_data,pos_latitude,pos_longitude,tag_id,gado_id) VALUES ('21/08/2016', '-23.563844' ,'-46.322525', '2','2');
答案 0 :(得分:15)
这是因为:
<强> OLD 强>
数据类型记录;保存旧数据库行的变量 行级触发器中的UPDATE / DELETE操作。这个变量是 在语句级触发器和INSERT操作中取消分配。
因此,您首先需要检查是否正在进行插入或更新。该信息可在TG_OP
中找到IF TG_OP = 'UPDATE' THEN
-- some code involving OLD
ELSE
-- other code