Frage

Ich versuche, meinen ersten Trigger und Funktion zur Arbeit zu kommen, aber wie ich werfe Ausnahmen und Rückgabedaten richtig?

PostgreSQL 8.4.1

CREATE TABLE "SHIFTS" (
    id integer NOT NULL, -- SERIAL
    added timestamp without time zone DEFAULT now() NOT NULL,
    starts timestamp without time zone NOT NULL,
    ends timestamp without time zone NOT NULL,
    employee_id integer,
    modified timestamp without time zone,
    status integer DEFAULT 1 NOT NULL,
    billid integer,
    CONSTRAINT "SHIFTS_check" CHECK ((starts < ends))
);


-- Check if given shift time overlaps with existing data
CREATE OR REPLACE FUNCTION 
  shift_overlaps (integer, timestamp, timestamp)
RETURNS 
  boolean AS $$
DECLARE
  _employeeid ALIAS FOR $1;
  _start      ALIAS FOR $2;
  _end        ALIAS FOR $3;
BEGIN
  SELECT 
    COUNT(id) AS c
  FROM 
    "SHIFTS" 
  WHERE 
    employee_id = _employeeid AND 
    status = 1 AND
    (
      (starts BETWEEN _start AND _end)
      OR 
      (ends BETWEEN _start AND _end)
    )
  ;

  -- Return boolean
  RETURN (c > 0);
END;
$$
LANGUAGE 
  plpgsql
;


CREATE OR REPLACE FUNCTION
  check_shift()
RETURNS trigger AS '
BEGIN

  -- Bill ID is set, do not allow update
  IF tg_op = "UPDATE" THEN
    IF old.billid IS NOT NULL THEN
      RAISE EXCEPTION "Shift is locked"
    END IF;
  END IF;

  -- Check for overlap
  IF tg_op = "INSERT" THEN
    IF new.employee_id IS NOT NULL THEN
      IF shift_overlaps(new.employee_id, new.starts, new.ends) THEN
        RAISE EXCEPTION "Given time overlaps with shifts"
      END IF;
    END IF;
  END IF;

  -- Check for overlap
  IF tg_op = "UPDATE" THEN
    IF (new.employee_id IS NOT NULL) AND (new.status = 1) THEN
      IF shift_overlaps(new.employee_id, new.starts, new.ends) THEN
        RAISE EXCEPTION "Given time overlaps with shifts"
      END IF;
    END IF;
  END IF;

  RETURN new;
END
'
LANGUAGE
  plpgsql
;


-- Shift checker trigger
CREATE TRIGGER
  check_shifts
BEFORE
  INSERT OR UPDATE
ON 
  "SHIFTS"  
FOR EACH ROW EXECUTE PROCEDURE
  check_shift()
;

shift_overlaps ():

SQL error: ERROR: query has no destination for result data

check_shift ():

SQL error: ERROR: unrecognized exception condition "Shift is locked"
War es hilfreich?

Lösung

Sie haben einen Fehler hier bekommen:

SELECT 
    COUNT(id) AS c
  FROM 
    "SHIFTS" 
  WHERE 
    employee_id = _employeeid AND 
    status = 1 AND
    (
      (starts BETWEEN _start AND _end)
      OR 
      (ends BETWEEN _start AND _end)
    )
  ;

Eine solche in einem plpgsql Verfahren wählen hat SELECT INTO ... so sein:

DECLARE
 c INTEGER;
BEGIN
  SELECT 
    COUNT(id)
  INTO c
  FROM 
    "SHIFTS" 
  WHERE 
    employee_id = _employeeid AND 
    status = 1 AND
    (
      (starts BETWEEN _start AND _end)
      OR 
      (ends BETWEEN _start AND _end)
    )
  ;

  RETURN (c > 0);

END;

Und hier du hast das Semikolon am Ende der Leitung haben:

enter code here`RAISE EXCEPTION "Shift is locked";

Andere Tipps

Nicht sicher, was Sie versuchen, um herauszufinden. Sie verwalten Ihre eigenen Ausnahmen zu erhöhen, so dass das gut. Ich würde erwarten, dass jede Fehlerbehandlung im Code sein würde, die diese Methode hervorruft.

Wenn Sie etwas in dem Verfahren tun möchten, benötigen Sie einen AUSNAHME Abschnitt:

[<>] [DECLARE     Erklärungen] START     Aussagen AUSNAHME     WHEN Bedingung [OR Bedingung ...] THEN         handler_statements     [WHEN Bedingung [OR Bedingung ...] THEN           handler_statements       ...] END;

Aber im Allgemeinen erwartet ich, würde Sie es in dem Aufruf-Code behandeln würden.

Sie haben SELECT INTO verwenden, um einen Wert von einer Abfrage

zurück zu bekommen
DECLARE
  [...]
  c boolean;
SELECT 
    COUNT(id) INTO c
  FROM 
    "SHIFTS" 
  WHERE 
  [...]
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top