【问题标题】:multiple update pgsql using cursor使用游标多次更新 pgsql
【发布时间】:2017-02-02 06:11:30
【问题描述】:

此代码没有错误,但没有任何数据更改,请帮助我。我想从一些库存表中多次更新数量

drop FUNCTION SP_PROSES_STOCK(noresep bigint, p_post_cd varchar);
CREATE or replace FUNCTION SP_PROSES_STOCK(noresep bigint, p_post_cd varchar)
RETURNS void
LANGUAGE plpgsql
as $function$
DECLARE cursorData refcursor;
    v_item_cd varchar;
    v_quantity numeric;

begin

open cursorData FOR
select A.item_cd, A.quantity from trx_medical_resep B
inner join trx_resep_data A on A.medical_resep_seqno = B.medical_resep_seqno
where B.medical_resep_seqno = noresep; 
fetch next from cursorData into v_item_cd,v_quantity;
while (found)
loop
    update inv_pos_item set quantity = quantity - v_quantity 
    where item_cd = v_item_cd and pos_cd = p_post_cd;
end loop;
close cursorData;

END 
$function$

【问题讨论】:

    标签: sql postgresql sql-update plpgsql database-cursor


    【解决方案1】:

    我修改了您的函数以使其更短并使用 FOR。我还添加了 RAISE NOTICE 进行调试。可以试试吗:

    CREATE or replace FUNCTION SP_PROSES_STOCK(noresep bigint, p_post_cd varchar)
    RETURNS void
    LANGUAGE plpgsql
    as $function$
    DECLARE v_cursor record;
    
    BEGIN
    
       FOR v_cursor IN
           SELECT A.item_cd,
                  A.quantity
             FROM trx_medical_resep B
             JOIN trx_resep_data A ON A.medical_resep_seqno = B.medical_resep_seqno
            WHERE B.medical_resep_seqno = noresep
       LOOP
           RAISE NOTICE 'Changes for %', v_curosr; 
           UPDATE inv_pos_item
               SET quantity = quantity - v_cursor.quantity 
             WHERE item_cd = v_cursor.item_cd
               AND pos_cd = p_post_cd;
       END LOOP;
    END 
    $function$
    

    调试完成后,您可以删除 RAISE NOTICE。

    【讨论】:

      【解决方案2】:

      你不需要循环。单个 UPDATE 语句会快很多:

      CREATE or replace FUNCTION SP_PROSES_STOCK(noresep bigint, p_post_cd varchar)
        RETURNS void
      as 
      $function$
      begin
      
        update inv_pos_item 
           set quantity = quantity - v.quantity 
        from (
          select A.item_cd, A.quantity 
          from trx_medical_resep B
            join trx_resep_data A on A.medical_resep_seqno = B.medical_resep_seqno
          where B.medical_resep_seqno = noresep
        ) v
        where item_cd = v.item_cd and pos_cd = p_post_cd;
      
      END;
      $function$
      LANGUAGE plpgsql;
      

      【讨论】:

      • 谢谢大家,我的数据库有数据错误,还有字符串\r的添加,不知道怎么会这样,我用dbeaver输入数据样本
      【解决方案3】:

      有些场景需要光标。例如,假设您正在更新 1000 万行,并且在第 6 百万条记录处引发异常,更新将失败,然后它将回滚在失败之前更新的所有行。如果使用游标,它会变慢,但您可以更好地控制该过程,并能够绕过错误并继续发布更新。但话说回来,你的里程可能会有所不同......

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-06-18
        • 1970-01-01
        • 2019-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-14
        相关资源
        最近更新 更多