2017-03-24 12 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