使用 c#ExecuteNonQuery 插入后 MS Access 表未正确刷新
Posted
技术标签:
【中文标题】使用 c#ExecuteNonQuery 插入后 MS Access 表未正确刷新【英文标题】:MS Access table not refreshing correctly after inserting with c# ExecuteNonQuery 【发布时间】:2016-03-07 13:42:37 【问题描述】:使用外部 c# 应用程序在空的 MS Access 表中插入记录时出现奇怪的行为
我的流程是:
-
在 Access 内部,我使用 WshShell 对象执行 c# 控制台应用程序,并带有“waitOnReturn”,因此访问会一直等到 shell 结束。
c#只是连接数据库,执行非查询oledbCommand
当 shell 结束后 Access 恢复时,我尝试读取新记录,但出现错误:没有记录!。但是,如果我手动打开更新的表,记录就在那里!
所以,问题是插入后表格没有更新
这是我在 Access 中的代码
Dim wsh As Object
Dim waitOnReturn As Boolean
Dim errorCode As Integer
Set wsh = CreateObject("WScript.Shell")
waitOnReturn = True
errorCode = wsh.Run("UpdateTable.exe", vbMaximizedFocus, waitOnReturn)
If errorCode <> 0 Then GoTo Error:
Dim dbf As DAO.Database
Dim UpdatedTable As DAO.Recordset
Set dbf = CurrentDb
Set UpdatedTable = dbf.OpenRecordset("MyTable", dbOpenTable)
UpdatedTable.MoveFirst 'ERROR! No records found
但是记录已经插入!他们在那里!事实上,当我收到错误时,Access 会停止并进入调试模式。此时我手动打开“MyTable”并看到数据。然后,我关闭表,并恢复(继续)执行 Access 代码,现在找到记录并且代码运行顺利。
插入记录(本例中只有一条记录)的c#代码是这样的:
string connectionString = "Provider=Microsoft.JET.OLEDB.4.0;data source=" + pathToMyDB;
using (OleDbConnection connection = new OleDbConnection(connectionString))
connection.Open();
OleDbCommand command = connection.CreateCommand();
command.CommandText = "INSERT INTO MyTable ([Field1], [Field2])" + " VALUES (@Param1, @Param2)";
command.Parameters.Add("@Param1", OleDbType.WChar, 35);
command.Parameters.Add("@Param2", OleDbType.Date);
command.Parameters["@Param1"].Value = "my string";
command.Parameters["@Param2"].Value = DateTime.Now;
int insertedRowsCount = 0;
using (OleDbTransaction transaction = connection.BeginTransaction())
command.Transaction = transaction;
try
insertedRowsCount = command.ExecuteNonQuery();
catch (InvalidOperationException queryExecutionException)
transaction.Rollback();
ProcessQueryExecutionExceptions(queryExecutionException);
if (insertedRowsCount == 1)
transaction.Commit();
else
transaction.Rollback();
command.Parameters.Clear();
connection.Close();
在 Access 中,可能是什么问题?有没有办法在读取表格之前强制访问刷新或更新表格?我曾尝试在 movefirst 之前关闭并重新打开表,在 shell 执行后插入 DoEvents
... 没有任何效果:(
在c#中,代码有问题吗?我是否必须更改连接字符串、命令或事务中的某些内容才能强制更新表?
【问题讨论】:
也许在 Set dbf = ...之后尝试 dbf.TableDefs.Refresh,但不确定... 行:"INSERT INTO MyTable ([Field1], [Field2])" + "VALUES (@Param1, @Param2)";本质上等同于:“INSERT INTO MyTable ([Field1], [Field2]) VALUES (@Param1, @Param2)”;你确定语法是正确的吗?最好的问候, 你为什么只为一个插入命令使用 Transaction?这两个操作的准确时间是什么——一个在 C# 中,另一个在 Access 中?最好的问候, 【参考方案1】:这个问题并不是真正的 C# 代码问题。只是 Access 会话还不知道由外部进程添加的新记录。来自any 外部进程的INSERT
也会发生同样的事情。我用替代UpdateTable.exe
的VBScript 文件重现了这个问题
此 Access VBA 代码在 UpdatedTable.MoveFirst
处触发错误 3021,“无当前记录” ...
Dim dbf As DAO.Database
Dim UpdatedTable As DAO.Recordset
Dim wsh As Object
Dim waitOnReturn As Boolean
Dim errorCode As Integer
Set wsh = CreateObject("WScript.Shell")
waitOnReturn = True
errorCode = wsh.Run("C:\Windows\SysWOW64\cscript.exe C:\share\Access\vbscript\AdoInsert.vbs", vbMaximizedFocus, waitOnReturn)
'CreateObject("JRO.JetEngine").RefreshCache CurrentProject.Connection
Set dbf = CurrentDb
Set UpdatedTable = dbf.OpenRecordset("tblKaikus", dbOpenTable)
UpdatedTable.MoveFirst ' without RefreshCache -> ERROR 3021, "No current record."
启用CreateObject("JRO.JetEngine").RefreshCache
行使新添加的记录在当前Access 会话中立即可用,因此记录集MoveFirst
方法不会触发错误。
【讨论】:
哇!我忘了将您的完美解决方案标记为答案...对不起:(以上是关于使用 c#ExecuteNonQuery 插入后 MS Access 表未正确刷新的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 ExecuteNonQuery 在 VARCHAR(MAX) 列中插入超过 8000 个字符?
SQLite .NET 插入 ExecuteNonQuery 返回 1
VB.NET SQL Server 插入 - ExecuteNonQuery:连接属性尚未初始化