【问题标题】:how to for each loop on data table within another datatable如何为另一个数据表中的数据表上的每个循环
【发布时间】:2016-08-22 20:40:15
【问题描述】:

我有一个网络投票应用程序,它从 sql server 后端读取和处理订单并插入到 windss(jda) 中。

流程

1) 我从 sql server 表中读取了所有未处理的订单
2)然后我需要将订单分成两组
- 使用捆绑套件设置 1 个订单(1 个带有多个子订单的订单)
- 第 2 套只是没有捆绑套件的订单
3)然后在处理完每个订单后,我需要将 isprocessed sql 字段更新为 1

1) 读取所有订单的代码

Frmmain.vb

 dt = WebDatabase.GetAllOrdersFromDatabase()**'this method is below**

 For Each drow In dt.Rows
    If CDbl(WinDSSStoreNumber) = 123 Or CDbl(WinDSSStoreNumber) = 124 Then 
     ' Store 123 and 124 = customer service - only orders with qualifying source codes

我的问题是:

上面的每个检查商店是 123 还是 124 但现在我想为每个循环实现另一个循环,该循环读取数据表中第二个字段的所有 InvoiceHeader_Id,然后检查它是否有捆绑套件然后处理它并更新数据表中倒数第二个 isprocessed 字段,否则在没有任何捆绑套件的情况下处理订单,并为这些订单处理更新。非常感谢任何帮助,请在标记我的问题之前在下面的评论中问我任何问题。

WebData.vb

    Public Function GetAllOrdersFromDatabase() As DataTable
            DrivePath = "C:\Users\somjething\Documents\files\somefiles\"
            Dim ds As DataTable = Nothing
            WinDSS.connectionString = ConfigurationManager.AppSettings("WinDSS_Connection").Replace("%DrivePath%", DrivePath)
            ds = WinDSS.GetSysMst()

            If ds.Rows.Count > 0 Then
                WinDSSStoreNumber = ds.Rows(0)("store_no")

            End If
            Dim dt As New DataTable()
            Dim conn As New SqlConnection(ConfigurationManager.AppSettings("WebData_Connection") & ConfigurationManager.AppSettings("WebDataSource"))
            Dim cmd As SqlCommand
            Dim da As New SqlDataAdapter
            conn.Open()
            cmd = conn.CreateCommand()
            cmd.CommandType = CommandType.Text
        cmd.CommandText= SELECT InvoiceDetail_Id, InvoiceHeader_Id, ActualFreightCharge, AmountCollected, 
        ChargedActualFreight, CollectedExternally, CollectedThroughAR, DateInvoiced, InvoiceNo, 
        InvoiceType, LineSubTotal, MasterInvoiceNo, OrderInvoiceKey, Reference1, TotalAmount, 
        TotalTax, isprocessed, storetoprocess
            FROM dbo.InvoiceHeader 
        WHERE (isprocessed = 0) AND (storetoprocess = N'123')
  da.SelectCommand = cmd
        da.Fill(dt)
        conn.Close()

        Return dt
    End Function

附加信息

这是我的经理给我的信息:

遍历下面的每个

SELECT InvoiceDetail_Id, InvoiceHeader_Id, ActualFreightCharge, AmountCollected, 
ChargedActualFreight, CollectedExternally, CollectedThroughAR, DateInvoiced, InvoiceNo, 
InvoiceType, LineSubTotal, MasterInvoiceNo, OrderInvoiceKey, Reference1, TotalAmount, 
TotalTax, isprocessed, storetoprocess
FROM dbo.InvoiceHeader WHERE (isprocessed = 0) AND (storetoprocess = N'195')

使用上面的 InvoiceHeader_Id 循环遍历所有的订单信息。处理每个 Bundle (Kit/)

SELECT InvoiceHeader_Id, LineDetails_Id, LineDetail_Id, OrderLine_Id, GiftFlag, [References],
 GiftWrap, IsBundleParent, KitCode, KitQty, LevelOfService, LineSeqNo, LineType, 
MaxLineStatus, MaxLineStatusDesc, MinLineStatus, MinLineStatusDesc, MinShipByDate,
 OpenQty, OrderHeaderKey, OrderLineKey, OrderedQty, OriginalOrderedQty, OtherCharges,
 OverallStatus, PipelineKey, PrimeLineNo, ReceivingNode, RemainingQty, ReqCancelDate,
 ReqDeliveryDate, 
ReqShipDate, SCAC, ScacAndService, ScacAndServiceKey, ShipNode, ShipToID, ShipToKey,
 StatusQuantity, SubLineNo, SubstituteItemID, isprocessed
FROM dbo.OrderLine 
WHERE (isprocessed = 0) AND (InvoiceHeader_Id = 13) AND (IsBundleParent = 'Y')
ORDER BY PrimeLineNo, SubLineNo

对于下面上述列表查询中的每条记录,并添加零 (0) 美元金额。成本与记录上面的信息相关(您可能需要查询表来获取值) 从上面的记录中获取OrderLineKey,在下面查询得到关联的子项。

SELECT TOP (100) PERCENT dbo.BundleParentLine.InvoiceHeader_Id AS BPL_InvoiceHeader_Id, 
dbo.BundleParentLine.LineDetails_Id AS BPL_LineDetails_Id, dbo.BundleParentLine.LineDetail_Id AS BPL_LineDetail_Id, dbo.BundleParentLine.OrderLine_Id AS BPL_OrderLine_Id, dbo.BundleParentLine.BundleParentLine_id, dbo.BundleParentLine.SubLineNo AS BPL_SubLineNo, dbo.BundleParentLine.PrimeLineNo AS BPL_PrimeLineNo, dbo.BundleParentLine.OrderLineKey AS BPL_OrderLineKey, dbo.OrderLine.*
FROM dbo.BundleParentLine INNER JOIN dbo.OrderLine ON dbo.BundleParentLine.OrderLine_Id = dbo.OrderLine.OrderLine_Id AND dbo.BundleParentLine.LineDetail_Id = dbo.OrderLine.LineDetail_Id AND dbo.BundleParentLine.LineDetails_Id = dbo.OrderLine.LineDetails_Id AND dbo.BundleParentLine.InvoiceHeader_Id = dbo.OrderLine.InvoiceHeader_Id
WHERE (dbo.BundleParentLine.OrderLineKey = N'76873264832') AND (dbo.BundleParentLine.InvoiceHeader_Id = 13) AND (dbo.BundleParentLine.LineDetails_Id = 6)  AND  (dbo.OrderLine.isprocessed = 0)
ORDER BY BPL_PrimeLineNo, BPL_SubLineNo

处理后,设置isprocessed = 1

使用上面的 InvoiceHeader_Id 循环遍历所有的订单信息

SELECT InvoiceHeader_Id, LineDetails_Id, LineDetail_Id, OrderLine_Id, GiftFlag, [References],
 GiftWrap, IsBundleParent, KitCode, KitQty, LevelOfService, LineSeqNo, 
 LineType,
 MaxLineStatus, MaxLineStatusDesc, MinLineStatus, MinLineStatusDesc, MinShipByDate,
 OpenQty, OrderHeaderKey, OrderLineKey, OrderedQty, 
  OriginalOrderedQty, 
OtherCharges, OverallStatus, PipelineKey, PrimeLineNo, ReceivingNode, RemainingQty, 
ReqCancelDate, ReqDeliveryDate, ReqShipDate, SCAC, 
 ScacAndService,
 ScacAndServiceKey, ShipNode, ShipToID, ShipToKey, StatusQuantity, 
SubLineNo, SubstituteItemID, isprocessed
FROM   dbo.OrderLine
WHERE (isprocessed = 0) AND (InvoiceHeader_Id = 13) AND (IsBundleParent <> 'Y')
ORDER BY PrimeLineNo, SubLineNo

处理后,设置isprocessed = 1

【问题讨论】:

  • 你真的需要开始分组思考。你所描述的对我来说听起来很像一个更新声明。无需通过痛苦的行来循环遍历这一行。只需使用 where 谓词更新您需要的行。
  • @SeanLange 设置实际上是有道理的,但我将如何在上述上下文中使用它?我正在将所有订单放入数据表中,所以我现在如何将捆绑包和非捆绑包分成集合,我有两个查询都设置了 where 条件,但我不确定如何从数据表中过滤。
  • 根据您的描述,您根本不需要将此数据提取到 dotnet 中。它只是一个更新声明。我无法从您对您在此处尝试执行的操作的描述中做出足够清晰的说明,以便为您提供任何真实的代码。发布表定义、一些示例数据以及您在此运行后的期望将会有很大帮助。
  • 如果您纯粹根据数据库(表和需要发生的事情)来描述这一点,我们可以提供一个更新语句来执行您想要的操作,您可能会同意这大大简化了流程(并且因此使其更易于维护)
  • @SeanLange 我已经添加了我的经理给我的所有内容,如果您需要任何其他信息,请告诉我

标签: sql-server vb.net foreach datatable


【解决方案1】:

这不是一个答案,但我想提出这个来提示您进行一些澄清,这在 cmets 中不实用。

首先,关闭visual studio并打开SQL Server Management Studio并连接数据库

我们将构建一些选择语句来取回数据,然后我们可以考虑一个 UPDATE 语句

您发布的第一个查询为您提供了商店 195 的未处理标题(直接来自您的帖子)。我不知道您是否要对所有商店都这样做。将其粘贴到 SSMS 中并运行它

SELECT H.*
FROM dbo.InvoiceHeader H 
WHERE H.isprocessed = 0 AND H.storetoprocess = N'195'

现在,第二个查询为您提供针对具有 IsBundleParent='Y' 的标头的未处理行。

看!没有循环!

SELECT H.*, L.*
FROM dbo.InvoiceHeader H 
INNER JOIN
dbo.OrderLine L
ON L.InvoiceHeader_Id = H.InvoiceHeader_Id 
WHERE H.isprocessed = 0 AND H.storetoprocess = N'195'
AND L.isprocessed = 0 AND L.IsBundleParent = 'Y'

然后在您的解释中,您有 对于下面上述列表查询中的每条记录,并添加为零 (0) 美元金额,这对我来说没有意义,所以也许您可以澄清一下

现在我们将添加第三个查询,其中添加了 BundleParentLine(其中已经有内部连接,但它是一个非常奇怪的连接字段列表)

SELECT H.*, L.*, BPL.*
FROM dbo.InvoiceHeader H 
INNER JOIN
dbo.OrderLine L
ON L.InvoiceHeader_Id = H.InvoiceHeader_Id 
INNER JOIN
dbo.BundleParentLine BPL
ON BPL.OrderLine_Id = L.OrderLine_Id 
AND BPL.LineDetail_Id = L.LineDetail_Id 
AND BPL.LineDetails_Id = L.LineDetails_Id 
AND BPL.InvoiceHeader_Id = L.InvoiceHeader_Id    
WHERE H.isprocessed = 0 AND H.storetoprocess = N'195'
AND L.isprocessed = 0 AND L.IsBundleParent = 'Y'

那么在你的解释中你有After Processed, set isprocessed = 1,但是这里的'processed'是什么?是否只是将其设置为在表中处理?

为此,您只需编写UPDATE 语句。这是一种仅更新标头的方法(在我们了解您要执行的操作之前不要运行它)。这里的问题是要同时设置header和line来处理吗?

UPDATE InvoiceHeader
SET Processed = 1
WHERE isprocessed = 0 AND storetoprocess = N'195'

您的第四个查询似乎与IsBundleParent &lt;&gt; 'Y' 案例有关

同样,我们需要知道 添加为零 (0) 美元金额已处理 意味着什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    相关资源
    最近更新 更多