VB.Net OLEDB ExecuteNonQuery INSERT INTO - 对数据库没有影响

VB.Net OLEDB ExecuteNonQuery INSERT INTO - No effect on Database

这是我的问题: 我有下面的代码。 如果我调试我的代码并将查询直接复制到 MS Access 中,则查询工作得很好,但如果我从我的应用程序中执行它,则不会对 table 进行任何更改。

请注意,与数据库的连接是正常的,因为我在此之前做了几次 Select 工作得很好。

我可能在做一些愚蠢的事情,但它太大了,我花了很多时间才看到它。

我知道我应该在我的查询中使用参数,我最初是这样做的,但我在我的许多尝试中改变了它,我想这应该不会改变太多。

    Dim cmd As New OleDbCommand
    Dim sQuery As String = String.Empty

    Try
        cmd.CommandText = "DELETE * FROM tbl_Invoices"
        cmd.ExecuteNonQuery()
    Catch ex As Exception
        MsgBox("PrepareInvoicing Delete" & vbCrLf & ErrorToString())
        Exit Sub
    End Try

    'Insert into the Invoice table the fleet info with Usage for the invoicing period selected
    Try
        sQuery = String.Empty
        sQuery = sQuery & "INSERT INTO tbl_Invoices "
        sQuery = sQuery & "SELECT tbl_Fleet.CustomerName AS CustomerName, "
        sQuery = sQuery & "tbl_Fleet.CountryCode AS CountryCode, "
        sQuery = sQuery & "#" & DateSerial(InvoicingYear, InvoicingMonth + 1, 0) & "# AS InvoiceDate, "
        sQuery = sQuery & "tbl_Fleet.Area AS Area, "
        sQuery = sQuery & "tbl_Fleet.Group AS [Group], "
        sQuery = sQuery & "tbl_Fleet.Site_nm AS SiteName, "
        sQuery = sQuery & "tbl_Sites.RCS AS CustomerPO, "
        sQuery = sQuery & "tbl_Fleet.Site_Addr_1 AS SiteAddress1, "
        sQuery = sQuery & "tbl_Fleet.Site_Addr_2 AS SiteAddress2, "
        sQuery = sQuery & "tbl_Fleet.Site_Addr_ZIP AS ZIP, "
        sQuery = sQuery & "tbl_Fleet.Site_Addr_cty AS City, "
        sQuery = sQuery & "tbl_Fleet.model_nm AS ProductDescription, "
        sQuery = sQuery & "tbl_Fleet.product_no AS ProductNumber, "
        sQuery = sQuery & "tbl_Fleet.serial_no AS SerialNumber, "
        sQuery = sQuery & "tbl_Fleet.hostname AS hostname, "
        sQuery = sQuery & "tbl_Fleet.asset_no AS AssetNumber, "
        sQuery = sQuery & "tbl_Fleet.Grid AS Grid, "
        sQuery = sQuery & "tbl_Fleet.ChangeOrderID AS ChangeOrderID, "
        sQuery = sQuery & "tbl_Fleet.install_date AS InstalledDate, "
        sQuery = sQuery & "INT(((tbl_Fleet.install_date - temptbl_CO.ChangeOrderStartDate)/365.25)+1) AS YearInContract, "
        sQuery = sQuery & "(tbl_RM.BlackClicks + tbl_RM.AccentClicks) AS BlackPages, "
        sQuery = sQuery & "(tbl_RM.ColorClicks + tbl_RM.ProfessionalColorClicks) AS ColorPages "
        sQuery = sQuery & "FROM tbl_Fleet, "
        sQuery = sQuery & "tbl_Sites, "
        sQuery = sQuery & "tbl_RM, "
        sQuery = sQuery & "(SELECT DISTINCT tbl_Bases.ProductNumber, tbl_Bases.ChangeOrderID, tbl_Bases.ChangeOrderStartDate FROM tbl_Bases WHERE tbl_Bases.CustomerName = '" & mdlGlobalStuff.SelectedCustomerName & "' AND tbl_Bases.CountryCode = '" & mdlGlobalStuff.SelectedCountryCode & "')  AS temptbl_CO "
        sQuery = sQuery & "WHERE tbl_Fleet.CustomerName = '" & mdlGlobalStuff.SelectedCustomerName & "' "
        sQuery = sQuery & "AND tbl_Fleet.CountryCode = '" & mdlGlobalStuff.SelectedCountryCode & "' "
        sQuery = sQuery & "AND tbl_Fleet.LoadDate = #" & LoadFleetDate & "# "
        sQuery = sQuery & "AND MONTH(tbl_RM.RMDate) = " & Month(LoadUsageDate) & " "
        sQuery = sQuery & "AND YEAR(tbl_RM.RMDate) = " & Year(LoadUsageDate) & " "
        sQuery = sQuery & "AND tbl_Fleet.CustomerName = tbl_Sites.CustomerName "
        sQuery = sQuery & "AND tbl_Fleet.CountryCode = tbl_Sites.CountryCode "
        sQuery = sQuery & "AND tbl_Fleet.Site_nm = tbl_Sites.Site_nm "
        sQuery = sQuery & "AND tbl_Fleet.CustomerName = tbl_RM.CustomerName "
        sQuery = sQuery & "AND tbl_Fleet.CountryCode = tbl_RM.CountryCode  "
        sQuery = sQuery & "AND tbl_Fleet.serial_no = tbl_RM.SerialNumber "
        sQuery = sQuery & "AND tbl_Fleet.product_no = temptbl_CO.ProductNumber "
        sQuery = sQuery & "AND tbl_Fleet.ChangeOrderID = temptbl_CO.ChangeOrderID "
        cmd.CommandText = sQuery
        cmd.ExecuteNonQuery()
        MsgBox("Step 1")
    Catch ex As Exception
        MsgBox("PrepareInvoicing: Invoicing step 1" & vbCrLf & ErrorToString())
        Exit Sub
    End Try

    'Update the "non aging" Bases (if Base.contractYear = 0) in the Invoice table
    Try
        sQuery = String.Empty
        sQuery = sQuery & "UPDATE tbl_Invoices "
        sQuery = sQuery & "INNER JOIN tbl_Bases ON tbl_Bases.ProductNumber  =  tbl_Invoices.ProductNumber "
        sQuery = sQuery & "AND tbl_Bases.ChangeOrderID = tbl_Invoices.ChangeOrderID "
        sQuery = sQuery & "SET tbl_Invoices.Base = tbl_Bases.BasePrice "
        sQuery = sQuery & "WHERE tbl_Bases.CustomerName = '" & mdlGlobalStuff.SelectedCustomerName & "' "
        sQuery = sQuery & "AND tbl_Bases.CountryCode = '" & mdlGlobalStuff.SelectedCountryCode & "' "
        sQuery = sQuery & "AND tbl_Bases.ContractYear = 0 "
        cmd.CommandText = sQuery
        cmd.ExecuteNonQuery()
        MsgBox("Step 2")
    Catch ex As Exception
        MsgBox("PrepareInvoicing: Invoicing step 2" & vbCrLf & ErrorToString())
        Exit Sub
    End Try

    'Update the "aging" Bases (if Base.contractYear <> 0) in the Invoice table
    Try
        sQuery = String.Empty
        sQuery = sQuery & "UPDATE tbl_Invoices "
        sQuery = sQuery & "INNER JOIN tbl_Bases ON tbl_Bases.ProductNumber  =  tbl_Invoices.ProductNumber "
        sQuery = sQuery & "AND tbl_Bases.ChangeOrderID = tbl_Invoices.ChangeOrderID "
        sQuery = sQuery & "AND tbl_Bases.ContractYear =  tbl_Invoices.YearInContract  "
        sQuery = sQuery & "SET tbl_Invoices.Base = tbl_Bases.BasePrice "
        sQuery = sQuery & "WHERE tbl_Bases.CustomerName = '" & mdlGlobalStuff.SelectedCustomerName & "' "
        sQuery = sQuery & "AND tbl_Bases.CountryCode = '" & mdlGlobalStuff.SelectedCountryCode & "' "
        cmd.CommandText = sQuery
        cmd.ExecuteNonQuery()
        MsgBox("Done")
    Catch ex As Exception
        MsgBox("PrepareInvoicing: Invoicing step 3" & vbCrLf & ErrorToString())
        Exit Sub
    End Try

我将继续 post 这是一个答案,因为根据我的经验,它至少有 95% 的可能性适用。

当您添加本地数据文件时,例如MDB 或 ACCDB 文件,对于您的项目,它与所有其他源文件一起被复制到项目文件夹中。该文件是您项目的一部分,而不是您的应用程序的一部分。任何模式更改或默认数据都会添加到该文件,但在测试时 运行 时不会被触及。

当您构建项目时,该源文件会与您的 EXE 一起复制到输出文件夹。这是您的应用程序在 运行 时使用的副本。您保存的任何数据都会保存到该工作副本,而不是源文件。

默认情况下,每次构建时都会制作源文件的新副本并覆盖工作副本。这意味着,如果您在调试器中 运行 您的应用程序,保存一些数据,停止应用程序,更改代码,然后再次 运行 应用程序,您保存的数据将会消失。

因此,您可能犯的错误与许多错误一样,是您要么在源文件中查找您在 运行 时间保存的数据,要么在被下一个构建覆盖后的工作副本。这个 "issue" 的解决方案很简单。 Select 在解决方案资源管理器中打开您的数据文件,打开属性 window 并将 Copy to Output Directory 属性 设置为 Copy if Newer。这意味着当您构建时,如果源文件较新,工作副本将永远被覆盖,如果您修改了模式或编辑了默认数据,就会出现这种情况。如果您需要刷新您的工作数据库,您只需从输出文件夹中手动删除它或暂时将 Copy to Output Directory 设置回 Copy Always

您可能想知道为什么他们首先使用多个文件,但这是完全合乎逻辑的,实际上是一件好事。如果您只有一个文件并将其用于测试,那么在部署时会发生什么?您将不得不浪费时间清理那个文件,然后您可能会遗漏一些东西。这样,您只需继续使用您的调试副本进行测试,当您进行发布构建时,您将始终获得一个干净的数据文件。