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 - 对数据库没有影响的主要内容,如果未能解决你的问题,请参考以下文章
VB.Net OLEDB ExecuteNonQuery INSERT INTO - 对数据库没有影响
在 MS Access 中保存来自 VB.Net Windows 窗体的数据时出现错误 System.Data.OleDb.OleDbException:“标准表达式中的数据类型不匹配”。