如何在C#中将数据表插入Access数据库

3

我有一个access数据库中的2个表格

现在我想从一个表格中选择并将它们插入到另一个表格中。

这是我的代码,但它在Cmd.ExecuteNonQuery();行显示异常。

{"查询表达式中缺少运算符的语法错误'System.Object[]'。"}

代码如下:

public static void SetSelectedFeedIntoDB(Form2 frm2)
{
    string StrCon = System.Configuration.ConfigurationManager.ConnectionStrings["FeedLibraryConnectionString"].ConnectionString;
    OleDbConnection Connection = new OleDbConnection(StrCon);
    OleDbDataAdapter DataA = new OleDbDataAdapter("Select * from FeedLibrary where ID=" + frm2.FeedSelectListBox.SelectedValue, Connection);
    DataTable DTable = new DataTable();
    DataA.Fill(DTable);

    OleDbCommand Cmd = new OleDbCommand();
    Cmd.Connection = Connection;

    Connection.Open();

    foreach (DataRow DR in DTable.Rows)
    {
        Cmd.CommandText = "insert into SelectedFeeds Values(" + DR.ItemArray + ")";
        Cmd.ExecuteNonQuery();
    }

    Connection.Close();
}  

我应该怎么做才能解决这个问题?

1个回答

6
你的错误是由于将DataRow的ItemArray属性连接到字符串上引起的。在这种情况下,ItemArray(它是一个对象[]的实例)没有自动从其值生成字符串的方法,因此返回类名作为字符串"object[]",但当然这会产生无意义的SQL字符串。
"insert into SelectedFeeds Values(object[])";

但是您可以简单地构建一个SELECT .... INTO语句,它将为您完成一切而不使用DataTables和Adapters。

string cmdText = @"SELECT FeedLibrary.* INTO [SelectedFeeds] 
                   FROM FeedLibrary
                   where ID=@id";
using(OleDbConnection Connection = new OleDbConnection(StrCon))
using(OleDbCommand cmd = new OleDbCommand(cmdText, Connection))    
{
     Connection.Open();
     cmd.Parameters.Add("@id", OleDbType.Integer).Value = Convert.ToInt32( frm2.FeedSelectListBox.SelectedValue);
     cmd.ExecuteNonQuery();
}

然而,SELECT ... INTO 语句会创建目标表,但如果目标表已经存在,则会出现错误。为了解决这个问题,我们需要判断目标表是否存在。如果不存在,我们使用第一个 SELECT ... INTO 查询,否则我们使用 INSERT INTO ..... SELECT 语句。

 // First query, this creates the target SelectedFeeds but fail if it exists
 string createText = @"SELECT FeedLibrary.* INTO [SelectedFeeds] 
                       FROM FeedLibrary
                       where ID=@id";
 // Second query, it appends to SelectedFeeds but it should exists
 string appendText = @"INSERT INTO SelectedFeeds
                       SELECT * FROM FeedLibrary
                       WHERE FeedLibrary.ID=@id";

using(OleDbConnection Connection = new OleDbConnection(StrCon))
using(OleDbCommand cmd = new OleDbCommand("", Connection))    
{
     Connection.Open();

     // Get info about the SelectedFeeds table....
     var schema = Connection.GetSchema("Tables", 
                   new string[] { null, null, "SelectedFeeds", null});

     // Choose which command to execute....
     cmd.CommandText = schema.Rows.Count > 0 ? appendText : createText;

     // Parameter @id is the same for both queries
     cmd.Parameters.Add("@id", OleDbType.Integer).Value = Convert.ToInt32( frm2.FeedSelectListBox.SelectedValue);

     cmd.ExecuteNonQuery();
}

这里有两个不同的查询,第一个创建了与以前相同的SelectedFeeds表,第二个将数据添加到该表中。
为了发现目标表是否已经被创建,我调用Connection.GetSchema来检索包含一行的datatable(模式),如果表SelectedFeeds存在,则会返回一行,否则不返回任何行。
此时,我使用正确的语句设置OleDbCommand以执行。

1
谢谢,我从FeedLibrary中选择特定ID,那怎么样? - SaraniO
1
好的,已添加WHERE部分,使用参数而不是字符串拼接(当然,我假设ID字段在数据库中是整数类型)。 - Steve
1
谢谢你,我尝试了你的代码,第一次它成功了(创建了表),但之后该源无法添加到此表中,并出现异常:{"Table 'SelectedFeeds' already exists."} - SaraniO
1
如果表已经存在,则查询应更改为INSERT INTO .... SELECT。 - Steve
1
抱歉打扰您了,使用您编辑过的代码会出现以下异常 {"在查询表达式中出现语法错误(缺少运算符)'* FeedLibrary\r\n where FeedLibrary.ID=@i'."}。 - SaraniO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接