使用c#ExecuteOnQuery插入后MS Access表未正确刷新
使用外部c#应用程序在空MS Access表中插入记录时,我有一种奇怪的行为 我的过程是:使用c#ExecuteOnQuery插入后MS Access表未正确刷新,c#,ms-access,oledb,C#,Ms Access,Oledb,使用外部c#应用程序在空MS Access表中插入记录时,我有一种奇怪的行为 我的过程是: 从内部访问中,我使用WshShell对象执行c#console应用程序,并带有“waitOnReturn”,因此访问将等待shell结束 c#只是连接到数据库,并执行非查询oledbCommand 当shell结束后恢复访问时,我尝试读取新记录,但得到一个错误:无记录!。但是,如果我手动打开更新的表,记录就在那里 因此,问题在于插入后表不会更新 这是我在Access中的代码 将wsh作为对象进行调暗 Di
将wsh作为对象进行调暗
Dim waitOnReturn作为布尔值
将错误代码设置为整数
设置wsh=CreateObject(“WScript.Shell”)
waitOnReturn=True
errorCode=wsh.Run(“UpdateTable.exe”、vbMaximizedFocus、waitOnReturn)
如果错误代码为0,则转到错误:
Dim dbf作为DAO.Database
Dim可更新为DAO.Recordset
设置dbf=CurrentDb
Set updateTable=dbf.OpenRecordset(“MyTable”,dbOpenTable)
UpdateTable.MoveFirst'错误!没有发现任何记录
但是记录被插入了!他们在那儿!。事实上,当我得到错误时,访问停止并进入调试模式。此时,我手动打开“MyTable”,看到了数据。然后,我关闭表,恢复(继续)Access代码的执行,现在找到记录,代码平稳运行
插入记录的c#代码(在本例中,只有一条记录)如下所示:
在Access中,会出现什么问题?有没有办法在读取表之前强制access刷新或更新表?我尝试在movefirst之前关闭并重新打开表,在shell执行之后插入DoEvents
。。。什么都不管用:(
在c#中,代码是否有问题?我是否必须更改连接字符串、命令或事务中的某些内容以强制更新表?问题实际上不是c#代码问题。问题只是Access会话尚未意识到由外部进程添加的新记录。同样的问题任何外部进程的
INSERT
都可能出现g。我用VBScript文件替换UpdateTable.exe
此访问VBA代码在updateTable.MoveFirst
处触发错误3021,“无当前记录”
Dim dbf作为DAO.Database
Dim可更新为DAO.Recordset
将wsh设置为对象
Dim waitOnReturn作为布尔值
将错误代码设置为整数
设置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
设置dbf=CurrentDb
Set updateTable=dbf.OpenRecordset(“tblKaikus”,dbOpenTable)
UpdateTable.MoveFirst'不带刷新缓存->错误3021,“无当前记录。”
启用
CreateObject(“JRO.JetEngine”).RefreshCache
行使新添加的记录在当前访问会话中立即可用,因此recordsetMoveFirst
方法不会触发错误。问题实际上不是c代码问题。原因很简单,访问会话尚未意识到由外部进程添加的新记录来自任何外部进程的插入
也会发生同样的情况。我用VBScript文件替换UpdateTable.exe
此访问VBA代码在updateTable.MoveFirst
处触发错误3021,“无当前记录”
Dim dbf作为DAO.Database
Dim可更新为DAO.Recordset
将wsh设置为对象
Dim waitOnReturn作为布尔值
将错误代码设置为整数
设置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
设置dbf=CurrentDb
Set updateTable=dbf.OpenRecordset(“tblKaikus”,dbOpenTable)
UpdateTable.MoveFirst'不带刷新缓存->错误3021,“无当前记录。”
启用
CreateObject(“JRO.JetEngine”).RefreshCache
行可以使新添加的记录在当前访问会话中立即可用,因此recordsetMoveFirst
方法不会触发错误。可以在设置dbf=…之后尝试dbf.TableDefs.Refresh,但不确定…行:“INSERT INTO MyTable”([Field1],[Field2])“+”值(@Param1,@Param2)”;本质上与“插入MyTable([Field1],[Field2])值(@Param1,@Param2)”相同;您确定语法正确吗?好的,为什么只对一个insert命令使用Transaction?两个操作的准确时间是什么?一个在C#中,另一个在Access中?好的,可能在设置dbf=…之后尝试dbf.TableDefs.Refresh,但不确定…行:“insert INTO MyTable([Field1],[Field2]“+”值(@Param1,@Param2)”;本质上与“插入MyTable([Field1],[Field2])值(@Param1,@Param2)”相同;你确定语法正确吗?好的,为什么你只对一个insert命令使用Transaction?两个操作的准确时间是什么?一个在C#中,另一个在Access中?好的,哇!我忘了标记你的完美解决方案作为答案…抱歉:(哇!我忘了标记你的完美解决方案作为答案…对不起:(
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();
}