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

Posted

技术标签:

【中文标题】VB.Net OLEDB ExecuteNonQuery INSERT INTO - 对数据库没有影响【英文标题】:VB.Net OLEDB ExecuteNonQuery INSERT INTO - No effect on Database 【发布时间】:2016-08-19 08:06:54 【问题描述】:

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

请注意,与数据库的连接是正常的,因为在此之前我做了几个 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

【问题讨论】:

你确定连接字符串的东西吗?这些症状是一个强有力的线索,表明那里和项目文件的配置中有问题。你能发布连接字符串吗? (当然是Sql Injection和解析问题) 作为初学者,你能尝试一些简单的东西插入你的表格吗?这样你就知道是连接问题还是查询语法问题......另外 ExecuteNonQuery() 返回一个整数,指示有多少行受到影响,尝试显示这个值...... 当您调用ExecuteNonQuery 时,只有三种可能的结果。它可以抛出异常,在这种情况下出现问题;它可以返回零,在这种情况下没有要保存的更改;它可以返回一个非零值,在这种情况下,需要保存更改并保存它们。你的情况是哪一种?更多情况下,不是选项 3,这意味着一切都在按应有的方式工作,而这个人只是在错误的地方和/或错误的时间寻找数据。如果您是这种情况,我可以提供一个涉及设置单个属性的适当答案。 顺便说一句,除其他外,您应该学习使用 XML 文字,这意味着您可以避免所有丑陋且容易出错的字符串连接来构建 SQL 代码。 非常感谢您的帮助。我的问题还没有解决,至少我正在取得一些进展。 【参考方案1】:

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

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

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

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

因此,与许多人一样,您可能犯的错误是,您要么在源文件中查找运行时保存的数据,要么在工作副本中查找已保存的数据。被下一个构建覆盖。这个“问题”的解决方案很简单。在解决方案资源管理器中选择您的数据文件,打开“属性”窗口并将Copy to Output Directory 属性设置为Copy if Newer。这意味着当您构建时,只有在源文件较新时才会覆盖工作副本,如果您修改了架构或编辑了默认数据,就会出现这种情况。如果您需要刷新您的工作数据库,您只需从输出文件夹中手动将其删除或临时将Copy to Output Directory 设置回Copy Always

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

【讨论】:

非常感谢!! :-) 就是这个。我只是觉得很愚蠢,但现在一切正常。

以上是关于VB.Net OLEDB ExecuteNonQuery INSERT INTO - 对数据库没有影响的主要内容,如果未能解决你的问题,请参考以下文章

ASPX VB.Net OleDb 将参数插入查询

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

在 MS Access 中保存来自 VB.Net Windows 窗体的数据时出现错误 System.Data.OleDb.OleDbException:“标准表达式中的数据类型不匹配”。

vb.net 怎么操作数据库

更新查询在带有 MS Access 的 VB.NET 中不起作用

无法从 .NET OleDB.DataReader 检索行