使用 c# ExecuteNonQuery 插入后,MS Access table 无法正确刷新
MS Access table not refreshing correctly after inserting with c# ExecuteNonQuery
使用外部 C# 应用程序在空的 MS Access table 中插入记录时出现奇怪的行为
我的流程是:
- 我从 Access 内部使用 WshShell 对象执行 c# 控制台应用程序,'waitOnReturn',因此访问会一直等到 shell 结束。
- c#只是连接数据库,执行一个非查询的oledb命令
- 当 Access 在 shell 结束后恢复时,我尝试读取新记录,但出现错误:没有记录!。但是,如果我手动打开更新后的 table,记录就在那里!
所以,问题是 table 在插入
后没有更新
这是我在 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",看到了数据。然后,我关闭 table,并恢复(继续)执行 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 中,可能是什么问题?有没有办法在阅读之前强制访问刷新或更新 table ?我试图在 movefirst 之前关闭并重新打开 table,在 shell 执行之后插入 DoEvents
... 没有任何效果:(
在c#中,代码有问题吗?我是否必须更改连接字符串、命令或事务中的某些内容以强制更新 table?
这个问题并不是真正的 c# 代码问题。只是 Access 会话还不知道外部进程添加的新记录。来自 any 外部进程的 INSERT
也会发生同样的事情。我用替换 UpdateTable.exe
的 VBScript 文件重现了这个问题
此访问 VBA 代码触发错误 3021,"No current record" 在 UpdatedTable.MoveFirst
...
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# 应用程序在空的 MS Access table 中插入记录时出现奇怪的行为
我的流程是:
- 我从 Access 内部使用 WshShell 对象执行 c# 控制台应用程序,'waitOnReturn',因此访问会一直等到 shell 结束。
- c#只是连接数据库,执行一个非查询的oledb命令
- 当 Access 在 shell 结束后恢复时,我尝试读取新记录,但出现错误:没有记录!。但是,如果我手动打开更新后的 table,记录就在那里!
所以,问题是 table 在插入
后没有更新这是我在 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",看到了数据。然后,我关闭 table,并恢复(继续)执行 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 中,可能是什么问题?有没有办法在阅读之前强制访问刷新或更新 table ?我试图在 movefirst 之前关闭并重新打开 table,在 shell 执行之后插入 DoEvents
... 没有任何效果:(
在c#中,代码有问题吗?我是否必须更改连接字符串、命令或事务中的某些内容以强制更新 table?
这个问题并不是真正的 c# 代码问题。只是 Access 会话还不知道外部进程添加的新记录。来自 any 外部进程的 INSERT
也会发生同样的事情。我用替换 UpdateTable.exe
此访问 VBA 代码触发错误 3021,"No current record" 在 UpdatedTable.MoveFirst
...
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
方法不会触发错误。