今天遇到一个很诡异的问题。我在一张表中新增了一个字段。然后用如下脚本更新这个字段的值:update ibp_fund_information_tab set yield = 7.4520  where fund_code = '040003' and info_date = to_date('20081128', 'yyyymmdd');
update ibp_fund_information_tab set yield = 6.2900  where fund_code = '100025' and info_date = to_date('20081128', 'yyyymmdd');………………
update ibp_fund_information_tab set yield = 1.5000  where fund_code = 'YF0001' and info_date = to_date('20100514', 'yyyymmdd');如此六千多行。然后commit。在这同一个文件中,又继续做如下的更新操作:
UPDATE ibp_fund_information_tab f SET f.yield = 0.00 WHERE f.yield IS NULL;
COMMIT ;当这个文件执行到最后,却报了死锁的错误。报死锁错误的是这倒数第二句:
UPDATE ibp_fund_information_tab f SET f.yield = 0.00 WHERE f.yield IS NULL;百思不得其解,于是我重新来过,把新增的那个字段的值全部清空。
再把上面那个脚本分成了两个文件。第一个文件更新那六千多条,第二个文件更新剩下字段值为空的记录。
这一次,脚本没有报死锁的错误。但是又一个很诡异的现象:之前更新的六千多行中,值几乎全都变成了0。幸免的只有fund_code 不是纯数字的记录。这是为什么呢?请各位大侠指点一下,谢谢~~

解决方案 »

  1.   

    把最后条语句跟那6000多条一起commit呢?
      

  2.   

    你先用一条试下结果,这样就好排除了
    update ibp_fund_information_tab set yield = 7.4520     where fund_code = '040003' and info_date = to_date('20081128', 'yyyymmdd');
    commit;
    UPDATE ibp_fund_information_tab f SET f.yield = 0.00 WHERE f.yield IS NULL;
    COMMIT ;
      

  3.   

    表结构没什么特别的,fund_code和info_date是主键,yield的类型是Number。
      

  4.   

    我的建议是你多些一些commit,不要6000行了,1000行一个,而且,在commit后,稍微等一段时间再进行下一步的操作,这个问题我也没遇到过,只是凭感觉,你可以试下。
    希望能对你有帮助。
      

  5.   

    是不是fund_code 为纯数字的记录没有更新到啊!
      

  6.   

    to xuweiccssddnn: 您说的是避免发生这种错误的做法,现在这个问题已经通过调整两个脚本的顺序来解决了。thank you all the same;to da21: fund_code为数字的也是可以正常更新的,我单独抓了一些fund_code为数字的update语句来执行了一下,未发现异常。to lzbbob1985: 这个表只会在早上九点左右更新,其他时间不会变化。我做这个操作时,是下午一点半开始,一直折腾到三点半。
      

  7.   

    根据描述看不出什么问题。可能的情况:
      1。更新6k多行数据时,未全部更新。
      2。fund_code列是否含有空格等其他不易发现字符。
      3。是否在同一脚本变换两条update语句执行顺序,或者其结果是怎样。
      
      

  8.   

    同一个session执行脚本,怎么会报死锁呢? 原因:1)当你执行脚本时,有其它Session在处理这个表2)表中的触发器,而且触发器有BUG
      

  9.   

    WHERE f.yield IS NULL  能不能改成WHERE len(f.yield)=0 
      

  10.   


    len() = 0 和NULL  是两个概念
      

  11.   


    改变脚本顺序就可以了?那这个问题确实很灵异。我的做法是,如果有太多的更新语句的话,我会选择一个适当的位置来commit(太多的commit是影响性能的),不会全部commit,因为,太多的update语句同时commit可能造成死锁(不同的session同时操作这个表,其他的job、存储过程、函数同时操作这个表,都会出现死锁现象)。