根据 sql select 查询 C# 的结果更新 table 列的最佳方法是什么?

What is the best way to update a table column based on a result of a sql select query C#?

原查询:

with Tr As (
  SELECT
    DocDtls.Warehouse,
    Transactions.Code,
    DocDtls.zDate,
    Transactions.ID,
    Transactions.QtyIn,
    Transactions.QtyOut,
    Transactions.BalanceAfter
  FROM
    DocDtls
    INNER JOIN Transactions ON DocDtls.[PrimDocNum] = Transactions.[DocNum]
),
formatted_tr as (
  select
    ID,
    Code,
    QtyIn,
    QtyOut,
    BalanceAfter,
    LAG(BalanceAfter, 1, 0) Over (
      partition by Warehouse,
      Code
      order by
        Code,zDate,ID
    ) Prev_BlncAfter
  from
    Tr
  )
select ID,Code,QtyIn,QtyOut,BalanceAfter
,SUM(Prev_BlncAfter + QtyIn)-QtyOut As NewBlncAfter
 from formatted_tr
 group by ID,Code,QtyIn,QtyOut,BalanceAfter;
;

解释这个想法: 假设查询 returns Item X 的所有交易结果有 10 行,我需要遍历所有 10 行并设置 BalanceAfter( 对于第一个交易 QtyIn-QtyOut , 任何其他交易 (PreviousBalanceAfter+QtyIn)-QtyOut) 等等 .

我尝试过的: 我试图将查询结果放在 Datatable 中,然后使用 DataView 再次过滤它以获取 DataGridView 当前行 ID 的 NewBlncAfter,因此 Dataview 只有一行并将其保存在一个变量中 - 到目前为止工作良好 - 当我尝试遍历 DataGridview 中的所有行并更新 BalanceAfter 我得到时:

Must Declare Scalar Variable @Newblnc

您可以在此处找到完整代码: My Code

那么有没有一种直接的方法可以将所有交易的 BalanceAfter 更新为等于

编辑 #1:我使用了@Charliface 查询,结果是:

我使用旧查询来比较结果,BalanceAfter 应该在每一行中等于 NewBlncAfter

编辑 #2:使用 SUM 而不是 LAG 会导致计算错误,如果我多次使用查询,BalanceAfter 中的结果会成倍增加

ID  Code    QtyIn   QtyOut  BalanceAfter
9   100001  20000   0        20000
14  100001  0      6000      40000
21  100001  3500    0        60000
24  100001  0      3000      80000

主要思想和期望的结果例如:

ID  Code    QtyIn   QtyOut  BalanceAfter
9   100001  20000   0        20000
14  100001  0      6000      14000
21  100001  3500    0        17500
24  100001  0      3000      14500

公式为: 对于第一笔交易 QtyIn-QtyOut ,任何其他交易 (PreviousBalanceAfter+QtyIn)-QtyOut 等等。

首先,我认为完全没有理由将所有这些数据拉入 C#,然后更新 row-by-row(这是非常低效的)。您可以在单个批量更新中执行此操作。

不太清楚你想要什么结果,但你似乎只想分配一个 运行 SUM 计算,而不是 LAG.

此外:

  • 第二个 CTE 是不必要的,可以折叠到第一个。
  • OVER 中的同一列进行分区和排序毫无意义。
  • 最后的 GROUP BY 也没有任何意义而且看起来没有必要,因为您是按主键分组的。
WITH Tr AS (
  SELECT
    d.Warehouse,
    t.Code,
    d.zDate,
    t.ID,
    t.QtyIn,
    t.QtyOut,
    t.BalanceAfter,
    SUM(t.QtyIn - t.QtyOut) OVER (
      PARTITION BY d.Warehouse, t.Code
      ORDER BY d.zDate, t.ID
      ROWS UNBOUNDED PRECEDING
    ) BlncAfter
  FROM
    DocDtls d
    INNER JOIN Transactions t ON d.PrimDocNum = t.DocNum
  WHERE t.Code = @VariableCode
)
UPDATE Tr
SET BalanceAfter = BlncAfter;

最后一点:为什么要把这些信息存储在一个新列中呢?为什么不在需要时使用 SUM OVER 来计算它?