操作必须使用可更新的查询 - Excel 2007文件作为OleDB数据源

时间:2013-09-04 16:25:55

标签: c# .net sql excel oledb

尝试使用OLEDB更新Excel工作表中的字段时经常出现此错误。

这有时会起作用,但我经常会遇到这个错误。 (操作必须使用可更新的查询)

连接代码:

string filepath = "c:\\SampleFile.xls";
OleDbConnection MyConnection;
MyConnection = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + filepath + "';Extended Properties=Excel 8.0;");
con3 = MyConnection;
MyConnection.Open();
if (MyConnection.State != ConnectionState.Open)
{
    do
    {
        Thread.Sleep(50);
    } while (MyConnection.State != ConnectionState.Open);
}

以下是执行更新的代码:

linesx = "231,214,412"; //this is variable
string sqlx = string.Format("Update [Resolved Results$] set [Audit Result] = 'AUDITED' where [LineNo] IN ({0})", linesx);
OleDbCommand myCommand = new OleDbCommand();
myCommand.Connection = MyConnection;
myCommand.CommandText = sqlx;
try
{
    Console.WriteLine(sqlx);
    myCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
    updRes = "Failed! :("+Environment.NewLine+"ERROR: " + ex.Message + Environment.NewLine;                        
} 

注意:对于linesx的SAME值,这有时会有效,有时则无效

我还监视连接状态,以确保连接在打开之前关闭,并且在执行命令之前连接已打开。我已经尝试了多种方法来解决它,包括:为读取(con1)和更新命令(MyConnection)提供单独的连接,(当然,我确保在打开MyConnection之前con1已关闭)

我已经研究了很多关于这个问题的答案,我可以得到最多的答案是该文件没有写权限。 HOwever,该程序确实具有写权限(因为更新命令有时会工作,有时不工作)

有时更新命令在失败一次后会起作用(即我尝试更新两次或三次),有时它不会。

为什么会这样?我该如何解决这个问题?

更新1: 我尝试使用JET强加的 Microsoft.ACE.OLEDB.12.0 - 错误没有出现,但它不会更新表格!!!

更新2: 我正在使用多个连接到同一个文件,这可能导致了问题。连接是一个全局变量。 我改变了整个应用程序架构,只在需要时初始化连接,如 Damith 所说的,它就像一个魅力(它有99%的时间有效) 我花了很多时间在整个应用程序中实现这一变化。

非常感谢 Damith

我希望这有助于其他2 ^ n面临同样问题的人:D

更新3: 我想我知道修复另外1% - 有些函数可以创建多个线程,每个线程都会打开自己的连接 - 这可能会导致问题。解决方案是确保只有一个连接到Excel数据库。 (不一定是ConnectionState.Close,但con变量应该超出范围并且为null)

1 个答案:

答案 0 :(得分:2)

执行以下操作,在需要时创建连接。 using阻止处理连接对象。

var connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + filepath + "';Extended Properties=Excel 8.0;";
var sqlx = string.Format("Update [Resolved Results$] set [Audit Result] = 'AUDITED' where [LineNo] IN ({0})", linesx);
using (var connection = new OleDbConnection(connectionString))
using (var command = new OleDbCommand(sqlx , connection))
{
    try
    {
        connection.Open();
        command.ExecuteNonQuery();
    }
    catch (Exception ex)
    {
        updRes = "Failed! :("+Environment.NewLine+"ERROR: " + ex.Message + Environment.NewLine;
    }
}