數據庫中實付存在某個日期匯率錯誤,導致本位幣金額計算錯誤。通過函數重新計算本位幣金額以及匯率修正。

CREATE FUNCTION "public"."update_actully_amount_by_rate"("param1" text, "patem2" numeric, "from_" numeric, "to_" numeric)
  RETURNS "pg_catalog"."void" AS $BODY$
    DECLARE 
    opdata record;--主表數據
    adjust record;--調整單數據
    
    tempAmount_ numeric;
    totalAmount_ numeric;
    actuallys_ text[];
    actually_id text;
    BEGIN
    -- 匯率更新之後,應收本位幣金額修改
        raise notice '發佈日期: %',param1;
        raise notice '匯率: %',patem2;
        raise notice '原幣: %',from_;
        raise notice '本位幣: %',to_;
    --查詢收款單(不是代付)
    FOR opdata IN SELECT 
                                apd.* 
                                FROM tb_actually_paid_detail    apd
                                LEFT JOIN tb_actually_paid ap
                                on apd.actually_paid_id=ap.id
                                WHERE ap.payment_currency=from_--42
                                AND ap.payment_status=2 -- 已付款
                                AND ap.delete=false --未刪除
                                AND ap.payment_base_currency=to_--38 付款賬號本位幣幣種
                                AND to_char(ap.payment_date,'yyyy-mm-dd')=param1 LOOP--'2018-03-12'
            raise notice 'code: %',opdata.id;
            
            UPDATE tb_actually_paid_detail 
            SET exchange_rate=patem2,
            payment_base_amount=payment_amount*patem2,
            in_push=1
            WHERE id=opdata.id;
            -- 將主表ID存到數組,去重複
            IF actuallys_ @> ARRAY[opdata.actually_paid_id::text] THEN
            ELSE
                    SELECT array_append(actuallys_, opdata.actually_paid_id::text) INTO actuallys_;
            END IF;
            
            raise notice 'actuallys_: %',actuallys_;
    END LOOP;
    
    --查詢收款單(是代付)
    FOR opdata IN SELECT 
                                apd.* 
                                FROM tb_actually_paid_detail    apd
                                LEFT JOIN tb_actually_paid ap
                                on apd.actually_paid_id=ap.id
                                WHERE ap.payment_currency=from_--42
                                AND ap.payment_status=2 -- 已付款
                                AND ap.delete=false --未刪除
                                AND apd.replace_pay_base_currency=to_--38 代付本位幣幣種(團所屬幣種)
                                AND to_char(ap.payment_date,'yyyy-mm-dd')=param1 LOOP--'2018-03-12'
            raise notice 'code: %',opdata.id;
            
            UPDATE tb_actually_paid_detail 
            SET exchange_rate=patem2,
            payment_base_amount=payment_amount*patem2,
            in_push=1
            WHERE id=opdata.id;
            -- 將主表ID存到數組,去重複
            IF actuallys_ @> ARRAY[opdata.actually_paid_id::text] THEN
            ELSE
                    SELECT array_append(actuallys_, opdata.actually_paid_id::text) INTO actuallys_;
            END IF;
            
            raise notice 'actuallys_: %',actuallys_;
    END LOOP;
    
    --循環實付主表
    FOREACH actually_id IN ARRAY actuallys_ LOOP
            SELECT sum(payment_base_amount) FROM tb_actually_paid_detail WHERE actually_paid_id=actually_id::bigint INTO totalAmount_;
            raise notice 'totalAmount_: %',totalAmount_;
            
            UPDATE tb_actually_paid
            SET payment_base_amount=totalAmount_
            WHERE id=actually_id::bigint;
    END LOOP;
    
    RETURN;
END$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100

    邏輯:循環付款明細,根據付款日期,付款幣種,付款本位幣,付款狀態,刪除狀態查詢付款明細。再循環每個明細進行計算修改,再循環過程中保存付款主表ID,這裏申明瞭一個數組來存儲,並且過濾重複得數據。

第二個循環是查詢了代付的數據,如果有用到錯誤匯率的也做同樣的處理,第三個循環是計算主表的本位幣金額。

明細表中同一付款ID的原幣金額相加等於主表的原幣金額。

 

    寫這篇文章的時候想在函數中使用數組類型,但是沒有找到好的文章。雖然比較基礎,也是給遇到同樣問題的人節約時間吧。