Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ERROR: record "old" is not assigned yet

I'm having difficulties in this simple trigger. My purpose is to verify before inserting a new register if is there's a register with the same field content which is "tag_id". If NEW tag_id is the same tag_id of any register on my table "coordenadas", then it updates, if not, it inserts a new one. When I try to insert sth, I get the error:

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

I have this table:

    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
)

This trigger:

CREATE TRIGGER verifica_coo
BEFORE INSERT OR UPDATE ON coordenadas
   FOR EACH ROW EXECUTE PROCEDURE verifica_coo();

This function:

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;

My insert:

INSERT INTO coordenadas (pos_data,pos_latitude,pos_longitude,tag_id,gado_id) VALUES ('21/08/2016', '-23.563844' ,'-46.322525', '2','2');
like image 640
Jhonatan Souza Avatar asked Aug 21 '16 22:08

Jhonatan Souza


1 Answers

This is because:

OLD

Data type RECORD; variable holding the old database row for UPDATE/DELETE operations in row-level triggers. This variable is unassigned in statement-level triggers and for INSERT operations.

So you first need to check if you are doing an insert or update. That information is available in TG_OP

IF TG_OP = 'UPDATE' THEN
    -- some code involving OLD 
ELSE 
    -- other code
like image 171
e4c5 Avatar answered Nov 20 '22 10:11

e4c5