起步软件技术论坛-X3

 找回密码
 立即注册
搜索
查看: 3351|回复: 88

[请求]在一个事务中多次更新同一记录的问题**

[复制链接]
发表于 2008-3-3 10:50:38 | 显示全部楼层 |阅读模式
问题:有一个库存表,一个入库表,一个出库表.
在入库和出库对应的数据集的beforeapplyupdate事件中再处理库存表中的相关字段的值,可能会出现,入库和出库都要更新同一条记录,现在碰到的问题是如果前面有过更新了后面的更新语句就没有起到作用.平台中如何解决这种问题?谢谢!
回复

使用道具 举报

发表于 2008-3-3 11:11:02 | 显示全部楼层
把更新选项换成按主键更新
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-3-3 11:15:36 | 显示全部楼层
库存表示用sql在后台更新的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-3-3 11:16:27 | 显示全部楼层
库存表是在进出库数据集中抓取数据处理后,用sql在后台更新的
回复 支持 反对

使用道具 举报

发表于 2008-3-3 11:18:08 | 显示全部楼层
不明白,语句是没执行,还是语句执行了没起作用。后者的话,修改成正确的sql。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-3-3 11:29:59 | 显示全部楼层
执行sql语句的代码跑到过了,但是好像执行失败,因为前面已经执行更新过这条记录的sql了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-3-3 11:30:42 | 显示全部楼层
但是因为在同一个事务中,没有提交
回复 支持 反对

使用道具 举报

发表于 2008-3-3 11:51:37 | 显示全部楼层
beforeapplyupdate换成after事件呢?
回复 支持 反对

使用道具 举报

发表于 2008-3-3 11:52:05 | 显示全部楼层
把代码贴出来看看,不明白什么意思
回复 支持 反对

使用道具 举报

 楼主| 发表于 2008-3-3 13:16:03 | 显示全部楼层
try
     while not lDeltaDataSet.Eof do
     begin
       case lDeltaDataSet.UpdateKind of
        //修改                                                                              `
         TUpdateKind.ukModify:
         begin
           ls_new_billid := lDeltaDataSet.FieldByName('EIBD_BILLID').AsString;
           lf_new_inv_fee := lDeltaDataSet.FieldByName('EIBDCstdTtl').AsFloat;
           lDeltaDataSet.Prior;
           ls_old_billid := lDeltaDataSet.FieldByName('EIBD_BILLID').AsString;
           lf_old_in_fee := lDeltaDataSet.FieldByName('EIBDCstdTtl').AsFloat;
           If lf_new_inv_fee = '' then lf_new_inv_fee := lf_old_in_fee;
           If ls_new_billid = '' then ls_new_billid := ls_old_billid;
           lDeltaDataSet.Next;
           //恢复结算单开票金额
           ls_sql := 'SELECT COUNT(EBH_AUTOIN) lcount FROM EXP_BILL_HEAD WHERE EBH_AUTOIN = ' + QuotedStr(ls_old_billid);
           lQuery := TDbCommand.OpenSql(ls_sql);
           li_count := 0;
           while not lQuery.Eof do
           begin
             li_count := lQuery.FieldByName('lcount').AsInteger;
             lQuery.Next;
           end;
           lQuery.EmptyDataSet;
           If li_count = 1 Then
           begin
             ls_sql := 'SELECT EBH_INV_VALUTA  FROM EXP_BILL_HEAD WHERE EBH_AUTOIN = ' + QuotedStr(ls_old_billid);
             lQuery := TDbCommand.OpenSql(ls_sql);
             lf_inv_available_valuta := lQuery.FieldByName('EBH_INV_VALUTA').AsFloat;

             If lf_inv_available_valuta < lf_old_in_fee Then
             begin
               Business.Forms.Dialogs.ShowMessage('恢复结算单开票金额时出错:编号为' + ls_old_billid + '的结算单的已开票金额,不够扣减。');
               SysUtils.Abort;
             end;

             If lf_inv_available_valuta - lf_old_in_fee = 0 Then
             begin
               ls_bill_inv_status := '20';
             end
             Else
             begin
               ls_bill_inv_status := '40';
             end;
*********************************************************************************
             ls_sql := 'UPDATE EXP_BILL_HEAD SET EBH_INV_VALUTA = EBH_INV_VALUTA - ' +  floattostr(lf_old_in_fee) +
                        ', EBH_STATUS = ' + QuotedStr(ls_bill_inv_status) + 'WHERE EBH_AUTOIN = ' + QuotedStr(ls_old_billid);
             TDbCommand.ExcSqlex(ls_sql,lQueryex);
           end;
**************************************************************************************
           //累加结算单开票金额
           ls_sql := 'SELECT COUNT(EBH_AUTOIN) lcount FROM EXP_BILL_HEAD WHERE EBH_AUTOIN = ' + QuotedStr(ls_new_billid);
           lQuery := TDbCommand.OpenSql(ls_sql);
           li_count := 0;
           while not lQuery.Eof do
           begin
              li_count := lQuery.FieldByName('lcount').AsInteger;
              lQuery.Next;
           end;
           If li_count = 1 Then
           begin
             ls_sql := 'SELECT EBH_ALL_VALUTA - EBH_INV_VALUTA INV_AVAILABLE_VALUTA FROM EXP_BILL_HEAD WHERE EBH_AUTOIN = ' + QuotedStr(ls_new_billid);
             lQuery := TDbCommand.OpenSql(ls_sql);
             lf_inv_available_valuta := lQuery.FieldByName('INV_AVAILABLE_VALUTA').AsFloat;

             If lf_inv_available_valuta + lf_old_in_fee < lf_new_inv_fee Then
             begin
               Business.Forms.Dialogs.ShowMessage('累加结算单开票金额时出错:编号为' + ls_new_billid + '的结算单的已开票金额,超出结算金额。');
               SysUtils.Abort;
             end;

             If lf_inv_available_valuta + lf_old_in_fee - lf_new_inv_fee = 0 Then
             begin
               ls_bill_inv_status := '50';
             end
             Else
             begin
               ls_bill_inv_status := '40';
             end;
********************************************************************
             ls_sql := 'UPDATE EXP_BILL_HEAD SET EBH_INV_VALUTA = EBH_INV_VALUTA + ' + floattostr(lf_new_inv_fee) +
                       ', EBH_STATUS = ' + QuotedStr(ls_bill_inv_status) + 'WHERE EBH_AUTOIN = ' + QuotedStr(ls_new_billid);
             TDbCommand.ExcSqlex(ls_sql,lQueryex);
*************************************************************************
           end
           Else
           begin
             Business.Forms.Dialogs.ShowMessage('累加结算单开票金额时出错:编号为' + ls_new_billid + '的结算单不存在,不可累加。');
             SysUtils.Abort;
             Exit;
           end;

         end;
         //插入
         TUpdateKind.ukInsert:
         begin
           ls_new_billid := lDeltaDataSet.FieldByName('EIBD_BILLID').AsString;
           lf_new_inv_fee := lDeltaDataSet.FieldByName('EIBDCstdTtl').AsFloat;
           //累加结算单开票金额
           ls_sql := 'SELECT COUNT(EBH_AUTOIN) lcount FROM EXP_BILL_HEAD WHERE EBH_AUTOIN = ' + QuotedStr(ls_new_billid);
           lQuery := TDbCommand.OpenSql(ls_sql);
           li_count := 0;

           while not lQuery.Eof do
           begin
              li_count := lQuery.FieldByName('lcount').AsInteger;
              lQuery.Next;
           end;
           If li_count = 1 Then
           begin
             ls_sql := 'SELECT EBH_ALL_VALUTA - EBH_INV_VALUTA INV_AVAILABLE_VALUTA FROM EXP_BILL_HEAD WHERE EBH_AUTOIN = ' + QuotedStr(ls_new_billid);
             lQuery := TDbCommand.OpenSql(ls_sql);
             lf_inv_available_valuta := lQuery.FieldByName('INV_AVAILABLE_VALUTA').AsFloat;

             If lf_inv_available_valuta < lf_new_inv_fee Then
             begin
               Business.Forms.Dialogs.ShowMessage('累加结算单开票金额时出错:编号为' + ls_new_billid + '的结算单的已开票金额,超出结算金额。');
               SysUtils.Abort;
             end;

             If lf_inv_available_valuta - lf_new_inv_fee = 0 Then
             begin
               ls_bill_inv_status := '50';
             end
             Else
             begin
               ls_bill_inv_status := '40';
             end;
***********************************************************************
             ls_sql := 'UPDATE EXP_BILL_HEAD SET EBH_INV_VALUTA = EBH_INV_VALUTA + ' + floattostr(lf_new_inv_fee) +
                       ', EBH_STATUS = ' + QuotedStr(ls_bill_inv_status) + 'WHERE EBH_AUTOIN = ' + QuotedStr(ls_new_billid);
             TDbCommand.ExcSqlex(ls_sql,lQueryex);
************************************************************************************
           end
           Else
           begin
             Business.Forms.Dialogs.ShowMessage('累加结算单开票金额时出错:编号为' + ls_new_billid + '的结算单不存在,不可累加1。');
             SysUtils.Abort;
             Exit;
           end;
         end;
         //删除
         TUpdateKind.ukDelete:
         begin
           ls_old_billid := lDeltaDataSet.FieldByName('EIBD_BILLID').AsString;
           lf_old_in_fee :=  lDeltaDataSet.FieldByName('EIBDCstdTtl').AsFloat;
           //恢复结算单开票金额
           ls_sql := 'SELECT COUNT(EBH_AUTOIN) lcount FROM EXP_BILL_HEAD WHERE EBH_AUTOIN = ' + QuotedStr(ls_old_billid);
           lQuery := TDbCommand.OpenSql(ls_sql);
           li_count := 0;
           while not lQuery.Eof do
           begin
              li_count := lQuery.FieldByName('lcount').AsInteger;
              lQuery.Next;
           end;
           If li_count = 1 Then
           begin
             ls_sql := 'SELECT EBH_INV_VALUTA INV_AVAILABLE_VALUTA FROM EXP_BILL_HEAD WHERE EBH_AUTOIN = ' + QuotedStr(ls_old_billid);
             lQuery := TDbCommand.OpenSql(ls_sql);
             lf_inv_available_valuta := lQuery.FieldByName('INV_AVAILABLE_VALUTA').AsFloat;

             If lf_inv_available_valuta < lf_old_in_fee Then
             begin
               Business.Forms.Dialogs.ShowMessage('恢复结算单开票金额时出错:编号为' + ls_old_billid + '的结算单的已开票金额,不够扣减2。');
               SysUtils.Abort;
             end;

             If lf_inv_available_valuta - lf_old_in_fee = 0 Then
             begin
               ls_bill_inv_status := '20';
             end
             Else
             begin
               ls_bill_inv_status := '40';
             end;
******************************************************************************
             ls_sql := 'UPDATE EXP_BILL_HEAD SET EBH_INV_VALUTA = EBH_INV_VALUTA - ' +  floattostr(lf_old_in_fee) +
                        ', EBH_STATUS = ' + QuotedStr(ls_bill_inv_status) + 'WHERE EBH_AUTOIN = ' + QuotedStr(ls_old_billid);
             TDbCommand.ExcSqlex(ls_sql,lQueryex);
***************************************************************************************
           end;
         end;
       else
         //
       end;
       lDeltaDataSet.NextStatus;
     end;
   finally
     lDeltaDataSet.Free;
   end;
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Justep Inc.

GMT+8, 2025-7-9 23:02 , Processed in 0.046887 second(s), 17 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表