Compara la enumeración postgresql en una función

I have a function defined that I would like to have update a record value it is modified.

CREATE FUNCTION update_project_status_away_from_started()
RETURNS TRIGGER AS $$
BEGIN
  IF OLD.status = 'started' THEN
    NEW.status = 'updating';
    RETURN NEW;
  END IF;
RETURN OLD;
END;
$$ language 'plpgsql';

However when I do update a row, I get the following error:

ERROR: operator does not exist: projectstatus = character varying

The enum is defined as follow:

CREATE TYPE projectstatus AS ENUM ('started', 'updating', 'complete');

My understanding of this is that the enum is being compared to a string and doesn't know what to do. Unfortunately I don't know how to cast the string ('started') to an enum. The postgresql pages at http://www.postgresql.org/docs/9.1/static/datatype-enum.html dont really help me out much. Anyone have any idea?

preguntado el 05 de mayo de 13 a las 12:05

Do you know, that this trigger will silently block todos updates to the rows, that have status != 'started'? -

+1 what @IgorRomanchenko said: RETURN OLD; will deny all updates and should probably be RETURN NEW;. -

2 Respuestas

Postgres is complaining that you need to cast that:

IF OLD.status = 'started'::projectstatus THEN
  NEW.status := 'updating'::projectstatus;
  RETURN NEW;
END IF;

Also, and as noted in Igor's answer, it's better to use := for assignment rather than the legacy (and deprecated, but still functional) = operador de asignación.

contestado el 05 de mayo de 13 a las 12:05

I'm sorry but "it's better to use := for assignment ...", the official documentation says nothing about this. postgresql.org/docs/11/plpgsql-statements.html , even more - "Equal (=) can be used instead of PL/SQL-compliant :=."! - Andriy Leshchuk

@AndriyLeshchuk: It's much easier to read (and maintain) code that isn't using the same operator for variable assignment and equality checks. (Try opening some old Basic or Visual Basic code if you have any of that lying around.) - denis de bernardo

Operador = is for comparison. Use := para asignación.

Algo como:

  IF OLD.status = 'started' THEN
    NEW.status := 'updating';
    RETURN NEW;
  END IF;

contestado el 05 de mayo de 13 a las 12:05

Esta respuesta es incorrecta. = works for assignment too when there's no ambiguity in plpgsql. It's undocumented because the Postgres team would like to get rid of the behavior, but it works fine. - denis de bernardo

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.