2017-03-24 2 views
0

Ich habe drei Tabellen:Postgresql RAISE EXCEPTION, wenn der Betrieb 0 oder weniger erhalten in Update

CREATE TABLE public.art_movimientos 
    (
     cmovimiento bigint NOT NULL DEFAULT nextval('art_movimientos_cmovimiento_seq'::regclass), 
     tipo character varying(3) NOT NULL, -- Tipos de Valores:... 
     fecha_mov timestamp without time zone NOT NULL, 
     documento integer NOT NULL, 
     control integer, 
     fecha_doc timestamp without time zone NOT NULL, 
     corden integer NOT NULL DEFAULT 0, 
     calmacen integer NOT NULL, 
     calmacen2 integer, 
     status character varying(13) NOT NULL DEFAULT 'PENDIENTE'::bpchar, -- PENDIENTE... 
     donado integer NOT NULL DEFAULT 0, 
     monto_mov numeric(11,2) NOT NULL DEFAULT 0.00, 
     monto_desc numeric(11,2) NOT NULL DEFAULT 0.00, 
     monto_total numeric(11,2) NOT NULL DEFAULT 0.00, 
     observacion text, 
     casiento integer, 
     crea_user character varying(25), 
     crea_date timestamp without time zone, 
     mod_user character varying(25), 
     mod_date timestamp without time zone, 
     cproveedor integer NOT NULL DEFAULT 0 
    ) 
CREATE TABLE public.art_movimientos_det 
(
    cmovimiento_det bigint NOT NULL DEFAULT nextval('art_movimientos_det_cmovimiento_det_seq'::regclass), 
    cmovimiento integer NOT NULL, 
    cart_generico integer NOT NULL, 
    cunidad integer NOT NULL DEFAULT 1, 
    cant numeric(11,2) NOT NULL DEFAULT 0.00, 
    iva numeric(11,2) NOT NULL DEFAULT 0.00, 
    costou numeric(11,2) NOT NULL DEFAULT 0.00, 
    crea_user character varying(25), 
    crea_date timestamp without time zone, 
    mod_user character varying(25), 
    mod_date timestamp without time zone, 
    cart_comercial integer NOT NULL, 
    costot numeric(11,2) NOT NULL DEFAULT 0.00 
) 
CREATE TABLE public.ordencompra_det 
(
    corden_det bigint NOT NULL DEFAULT nextval('ordencompra_det_corden_det_seq'::regclass), 
    corden integer NOT NULL, 
    cart_comercial integer NOT NULL, 
    cunidad integer NOT NULL DEFAULT 1, 
    cant numeric(11,2) NOT NULL DEFAULT 0.00, 
    costou numeric(11,2) NOT NULL DEFAULT 0.00, 
    iva numeric(11,0) NOT NULL DEFAULT 0.00, 
    costot numeric(11,2) NOT NULL DEFAULT 0.00, 
    crea_user character varying(25), 
    crea_date timestamp without time zone, 
    mod_user character varying(25), 
    mod_date timestamp without time zone, 
    cant_restante numeric(11,2) NOT NULL DEFAULT 0 
) 

ich eine Prozedur, die die cant_restante in ordencompra_det reduzieren:

UPDATE ordencompra_det AS od 
     SET cant_restante = cant_restante - s.cant_real 
     FROM (SELECT am.corden, md.cart_comercial,(md.cant*u.multiplicador)cant_real FROM art_movimientos am INNER JOIN art_movimientos_det md ON am.cmovimiento=md.cmovimiento INNER JOIN art_und u ON md.cunidad=u.cunidad WHERE md.cmovimiento=cmov) AS s 
     WHERE od.corden=s.corden and od.cart_comercial=s.cart_comercial 

Aber ich habe manchmal 0 oder weniger in cant_restante, wie kann ich eine Überprüfung durchführen, wenn das Update Ergebnis unter 0? Ich will keine negativen Werte "/, wenn ich negative Werte bekomme, Rollback das Update und eine Ausnahme auslösen?

Ich benutze postgresql Funktion (procedure) dafür (weil ich eine Menge Sachen in die DB)

Antwort

1

Es gibt mehr Möglichkeiten sind:

  • Verwendung Tabellenbedingung:

    CREATE TABLE ordencompra_det(
        ... 
        cant_restante numeric(11,2) NOT NULL DEFAULT 0 CHECK(can_restante >= 0), 
        ... 
    ) 
    
  • eine Prüffunktion Verwendung:

    CREATE OR REPLACE FUNCTION only_positive(numeric) 
    RETURNS numeric AS $$ 
    BEGIN 
        IF $1 < 0 THEN 
        RAISE EXCEPTION '%s is not positive', $1; 
        END IF; 
        RETURN $1; 
    END; 
    $$ LANGUAGE plpgsql IMMUTABLE STRICT; 
    

    UPDATE ordencompra_det SET cant_restante = only_positive (cant_restante - s.cant_real) ...

Der erste Weg sollte bevorzugt werden.

+0

Eigentlich habe ich vergessen, dass ich es tun kann! aber wenn die Funktion ausgeführt wird, gibt sie mir einen Fehler zurück, der die Prüfung verletzt, und ich möchte dem Benutzer den Grund zeigen, weil sie es nicht tun können! – JuJoGuAl

+1

Sie können einen ROW BEFORE-Trigger verwenden. Wenn die Triggerfunktion NULL zurückgibt, wird die aktuelle Zeilenaktualisierung übersprungen - verwenden Sie RAISE NOTICE oder RAISE WARNING statt RAISE EXCEPTION - dann wird es keine Ausnahme geben. –

+0

Ich habe eine Heck-Funktion, und war die Lösung für jetzt, aber was ist der Unterschied zwischen NOTICE WARNING und EXCEPTION? – JuJoGuAl

Verwandte Themen