2017-03-24 13 views
0

獲得小於或等於0我有三個表:PostgreSQL的引發異常時操作更新

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 
) 

我有一個過程,減少cant_restanteordencompra_det

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 

但有時我得到0或少於cant_restante,如果更新結果低於0,我該如何做檢查?我不想有負值「/,如果我得到負值,回滾更新並引發異常?

我爲它使用postgresql函數(過程)(因爲我在做很多東西在DB)

回答

1

有更多的可能性:

  • 使用表約束:

    CREATE TABLE ordencompra_det(
        ... 
        cant_restante numeric(11,2) NOT NULL DEFAULT 0 CHECK(can_restante >= 0), 
        ... 
    ) 
    
  • 用單向函數:

    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) ...

第一種方式應當是優選的。

+0

其實我忘了我可以做到!但是當函數被執行時,它會向我返回一個錯誤違規檢查,並且我想向用戶顯示原因,因爲他們無法做到這一點! – JuJoGuAl

+1

您可以使用ROW BEFORE觸發器。當觸發器函數返回NULL時,則跳過當前行更新 - 使用RAISE NOTICE或RAISE WARNING RAISE EXCEPTION - 然後不會有例外。 –

+0

我做了一個heck函數,現在是解決方案,但NOTICE WARNING和EXCEPTION之間有什麼區別? – JuJoGuAl