人间正道捡破烂 發表於 2023-2-10 10:03:00

delphi FireDAC使用ApplyUpdates批量提交数据

<p>简单的设计一下界面,大致如下:</p>
<p>要求:审核或者反审核用户选择的数据  </p>
<p>  1.正常点审核时,审核=true,审核人=当前用户名</p>
<p>  2.反审核时,审核=false,审核人=null</p>
<p><img src="https://img2023.cnblogs.com/blog/981841/202302/981841-20230209194258627-789996343.png"></p>
<p>&nbsp;实现代码:</p>
<p>&nbsp;</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">procedure</span><span style="color: rgba(0, 0, 0, 1)"> TForm1.UpdateData(flg: Boolean);
</span><span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
i, n, Errors: Integer;
PN, ID: </span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">begin</span>
<span style="color: rgba(0, 0, 255, 1)">if</span> flg <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
    PN :</span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">TEST</span><span style="color: rgba(128, 0, 0, 1)">'</span>   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">用户名,按业务自己处理</span>
<span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
    PN :</span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">NULL</span><span style="color: rgba(128, 0, 0, 1)">'</span>;    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">反审核,按业务自己处理</span>

<span style="color: rgba(0, 0, 255, 1)">with</span> FDQuery1 <span style="color: rgba(0, 0, 255, 1)">do</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
    FetchOptions.AutoClose :</span>= False;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">取消自动关闭</span>
    CachedUpdates := True;            <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">开户快储功能</span>
    n := TV.datacontroller.GetSelectedCount;   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">当前选择记录的长度<br>{*<br>  我不知道你们有没有出现过这种问题,当我ctrl+a全选数据时,就会弹错,原因是此时recno指到了最后一条记录<br>  导致下面的 <span style="color: rgba(0, 0, 0, 1)">TV.Controller.SelectedRows[<span style="color: rgba(128, 0, 128, 1)">i].Focuesd:=true;</span></span> 语句出错,所以我下面做了个判断,当选择了所有的记录时,手动把游标移动到了第一条<br>*}</span>
  if n=RecordCount then  <br>&nbsp;&nbsp;&nbsp;frist;
<span style="color: rgba(0, 0, 255, 1)">try</span>
    <span style="color: rgba(0, 0, 255, 1)">for</span> i := <span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 0, 255, 1)">to</span> n - <span style="color: rgba(128, 0, 128, 1)">1</span> <span style="color: rgba(0, 0, 255, 1)">do</span>
   <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)"> <br>     TV.Controller.SelectedRows[<span style="color: rgba(128, 0, 128, 1)">i].Focuesd:=true;</span>
      Edit;
      FieldByName(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">审核</span><span style="color: rgba(128, 0, 0, 1)">'</span>).Value := BoolToStr(flg);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">按业务自己处理</span>
      FieldByName(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">审核人</span><span style="color: rgba(128, 0, 0, 1)">'</span>).Value := PN;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">按业务自己处理</span>
<span style="color: rgba(0, 0, 0, 1)">      Next;
      </span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
      FDConnection1.StartTransaction;   </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">开始事务</span>
      Errors := ApplyUpdates(<span style="color: rgba(128, 0, 128, 1)">0</span>);      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">尝试批量更新,并返回错误值</span>
    <span style="color: rgba(0, 0, 255, 1)">finally</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> Errors &gt; <span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 0, 255, 1)">then</span><span style="color: rgba(0, 0, 0, 1)">
      FDConnection1.Rollback</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">出错回滚</span>
      <span style="color: rgba(0, 0, 255, 1)">else</span>
      <span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
      FDConnection1.Commit;  
      CommitUpdates;</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 清除所有异动记录</span>
      Refresh;          <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">更新数据</span>
      <span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
      CachedUpdates :</span>= False;      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">关闭快储</span>
    <span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">end</span>;      </pre>
</div>
<pre> Errors := ApplyUpdates(0<span style="color: rgba(128, 0, 128, 1)">);<br></span> 参数为0时,表示不容忍任何错误,直接回滚<br> 参数为-1时,表示尽量保存修改,更新完后再报错误.<br>比如你要更新十条数据,其中有五条会成功,五条会失败,此时如果你参数为0的话,程序就会直接放弃所有变更,也就是不更新了.如果参数为-1,则会更新五条,然后再告诉你有五条出错了<br><br>我用SQL语句一句句的更新,同样53条数据的时间对比如下,也不知道是不是我的数据量太少,没有体现出ApplyUpdates的性能,还是什么原因.服务器的负荷是减少了,但花费的时间变多了</pre>
<img src="https://img2023.cnblogs.com/blog/981841/202302/981841-20230210191511864-2124643917.png">
<p>&nbsp;</p>
<h1><strong>&nbsp;说一下多选数据时的问题:</strong></h1>
<p><img src="https://img2023.cnblogs.com/blog/981841/202302/981841-20230211105227821-417201499.png"></p>
<p>&nbsp;</p>
<p>然后ACXTV.Controller.SelectedRows.index这个属性,在使用时也要注意一下,这个值不一定会等于RecNo的值,所以我们不能用它来设置游标位置.</p>
<p><img src="https://img2023.cnblogs.com/blog/981841/202302/981841-20230211105804948-492678241.png"></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;<img src="https://img2023.cnblogs.com/blog/981841/202302/981841-20230211105415006-1008552044.png"></p>
<p>&nbsp;2023-02-18</p>
<p>以下是ChatGPT的回复</p>
<div class="cnblogs_code">
<pre>---<span style="color: rgba(0, 0, 0, 1)">
Q: 请用delphi写出用tfdquery组件实现批量更新的代码,要带注释
A:</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">定义变量</span>
<span style="color: rgba(0, 0, 255, 1)">var</span><span style="color: rgba(0, 0, 0, 1)">
FDQuery1: TFDQuery;
i: Integer;

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">初始化</span>
FDQuery1 := TFDQuery.<span style="color: rgba(0, 0, 255, 1)">Create</span>(<span style="color: rgba(0, 0, 255, 1)">nil</span><span style="color: rgba(0, 0, 0, 1)">);

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">设置SQL语句</span>
FDQuery1.SQL.Text := <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">update table set field1=:field1,field2=:field2 where id=:id</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">循环更新</span>
<span style="color: rgba(0, 0, 255, 1)">for</span> i := <span style="color: rgba(128, 0, 128, 1)">0</span> <span style="color: rgba(0, 0, 255, 1)">to</span> <span style="color: rgba(128, 0, 128, 1)">10</span> <span style="color: rgba(0, 0, 255, 1)">do</span>
<span style="color: rgba(0, 0, 255, 1)">begin</span><span style="color: rgba(0, 0, 0, 1)">
FDQuery1.ParamByName(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">field1</span><span style="color: rgba(128, 0, 0, 1)">'</span>).AsString := <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">value1</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
FDQuery1.ParamByName(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">field2</span><span style="color: rgba(128, 0, 0, 1)">'</span>).AsString := <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">value2</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
FDQuery1.ParamByName(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">id</span><span style="color: rgba(128, 0, 0, 1)">'</span>).AsInteger :=<span style="color: rgba(0, 0, 0, 1)"> i;
FDQuery1.ExecSQL;
</span><span style="color: rgba(0, 0, 255, 1)">end</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">释放资源</span>
<span style="color: rgba(0, 0, 0, 1)">FDQuery1.Free;</span>---</pre>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<pre><br><br><br></pre><br><br>
来源:https://www.cnblogs.com/yoooos/p/17106847.html
頁: [1]
查看完整版本: delphi FireDAC使用ApplyUpdates批量提交数据