我正在尝试从一个Access数据库文件中获取表,将它们添加到具有完全相同结构但具有不同信息的另一个Access数据库文件中。我需要覆盖任何现有的表。我差不多完成了我的项目,这是我的砖墙。
我使用名为DatabaseHandling.cs的单独类文件来处理Access数据库文件。
这是我当前的整个DatabaseHandling.cs代码。这一点现在保持最新。
代码:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Text;
namespace LCR_ShepherdStaffupdater_1._0
{
public class DatabaseHandling
{
static DataTable datatableB = new DataTable();
static DataTable datatableA = new DataTable();
public static DataSet datasetA = new DataSet();
public static DataSet datasetB = new DataSet();
static OleDbDataAdapter adapterA = new OleDbDataAdapter();
static OleDbDataAdapter adapterB = new OleDbDataAdapter();
static string connectionstringA = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + Settings.getfilelocationA();
static string connectionstringB = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + Settings.getfilelocationB();
static OleDbConnection dataconnectionB = new OleDbConnection(connectionstringB);
static OleDbConnection dataconnectionA = new OleDbConnection(connectionstringA);
static DataTable tableListA;
static DataTable tableListB;
static public void addTableA(string table, bool addtoDataSet)
{
dataconnectionA.Open();
datatableA = new DataTable(table);
try
{
OleDbCommand commandselectA = new OleDbCommand("SELECT * FROM [" + table + "]", dataconnectionA);
adapterA.SelectCommand = commandselectA;
adapterA.Fill(datatableA);
}
catch
{
Logging.updateLog("Error: Tried to get " + table + " from DataSetA. Table doesn't exist!", true, false, false);
}
if (addtoDataSet == true)
{
datasetA.Tables.Add(datatableA);
Logging.updateLog("Added DataTableA: " + datatableA.TableName.ToString() + " Successfully!", false, false, false);
}
dataconnectionA.Close();
}
static public void addTableB(string table, bool addtoDataSet)
{
dataconnectionB.Open();
datatableB = new DataTable(table);
try
{
OleDbCommand commandselectB = new OleDbCommand("SELECT * FROM [" + table + "]", dataconnectionB);
adapterB.SelectCommand = commandselectB;
adapterB.Fill(datatableB);
}
catch
{
Logging.updateLog("Error: Tried to get " + table + " from DataSetB. Table doesn't exist!", true, false, false);
}
if (addtoDataSet == true)
{
datasetB.Tables.Add(datatableB);
Logging.updateLog("Added DataTableB: " + datatableB.TableName.ToString() + " Successfully!", false, false, false);
}
dataconnectionB.Close();
}
static public string[] getTablesA(string connectionString)
{
dataconnectionA.Open();
tableListA = dataconnectionA.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" });
string[] stringTableListA = new string[tableListA.Rows.Count];
for (int i = 0; i < tableListA.Rows.Count; i++)
{
stringTableListA[i] = tableListA.Rows[i].ItemArray[2].ToString();
}
dataconnectionA.Close();
return stringTableListA;
}
static public string[] getTablesB(string connectionString)
{
dataconnectionB.Open();
tableListB = dataconnectionB.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" });
string[] stringTableListB = new string[tableListB.Rows.Count];
for (int i = 0; i < tableListB.Rows.Count; i++)
{
stringTableListB[i] = tableListB.Rows[i].ItemArray[2].ToString();
}
dataconnectionB.Close();
return stringTableListB;
}
static public void createDataSet()
{
string[] tempA = getTablesA(connectionstringA);
string[] tempB = getTablesB(connectionstringB);
int percentage = 0;
int maximum = (tempA.Length + tempB.Length);
Logging.updateNotice("Loading Tables...");
Logging.updateLog("Started Loading File A", false, true, false);
for (int i = 0; i < tempA.Length ; i++)
{
if (!datasetA.Tables.Contains(tempA[i]))
{
addTableA(tempA[i], true);
percentage++;
Logging.loadStatus(percentage, maximum);
}
else
{
datasetA.Tables.Remove(tempA[i]);
addTableA(tempA[i], true);
percentage++;
Logging.loadStatus(percentage, maximum);
}
}
Logging.updateLog("Finished loading File A", false, true, false);
Logging.updateLog("Started loading File B", false, true, false);
for (int i = 0; i < tempB.Length ; i++)
{
if (!datasetB.Tables.Contains(tempB[i]))
{
addTableB(tempB[i], true);
percentage++;
Logging.loadStatus(percentage, maximum);
}
else
{
datasetB.Tables.Remove(tempB[i]);
addTableB(tempB[i], true);
percentage++;
Logging.loadStatus(percentage, maximum);
}
}
Logging.updateLog("Finished loading File B", false, true, false);
}
static public DataTable getDataTableA()
{
datatableA = datasetA.Tables[Settings.textA];
return datatableA;
}
static public DataTable getDataTableB()
{
datatableB = datasetB.Tables[Settings.textB];
return datatableB;
}
static public DataSet getDataSetA()
{
return datasetA;
}
static public DataSet getDataSetB()
{
return datasetB;
}
static public void InitiateCopyProcessA()
{
DataSet tablesA;
tablesA = DatabaseHandling.getDataSetA();
foreach (DataTable table in tablesA.Tables)
{
OverwriteTable(table, table.TableName);
Logging.updateLog("Copied " + table.TableName + " successfully.", false, true, false);
}
}
static void OverwriteTable(DataTable sourceTable, string tableName)
{
using (var destConn = new OleDbConnection(connectionstringA))
using (var destCmd = new OleDbCommand(tableName, destConn) { CommandType = CommandType.TableDirect })
using (var destDA = new OleDbDataAdapter(destCmd))
{
// Since we're using a single table, we can have the CommandBuilder
// generate the appropriate INSERT and DELETE SQL statements
using (var destCmdB = new OleDbCommandBuilder(destDA))
{
destCmdB.QuotePrefix = "["; // quote reserved column names
destCmdB.QuotePrefix = "]";
destDA.DeleteCommand = destCmdB.GetDeleteCommand();
destDA.InsertCommand = destCmdB.GetInsertCommand();
// Get rows from destination, and delete them
var destTable = new DataTable();
destDA.Fill(destTable);
foreach (DataRow dr in destTable.Rows)
{
dr.Delete();
}
destDA.Update(destTable);
// Set rows from source as Added, so the DataAdapter will insert them
foreach (DataRow dr in sourceTable.Rows)
{
dr.SetAdded();
}
destDA.Update(sourceTable);
}
}
}
}
}
我只想获取内存中的Datatable并将其写入.MDB文件。我一直试图这样做超过30个小时。
最新编辑:
好的,添加了新代码。我收到一个新的运行时错误: FROM子句中的语法错误。
代码:
static public void InitiateCopyProcessA()
{
DataSet tablesA;
tablesA = DatabaseHandling.getDataSetA();
foreach (DataTable table in tablesA.Tables)
{
OverwriteTable(table, table.TableName);
Logging.updateLog("Copied " + table.TableName + " successfully.", false, true, false);
}
}
static void OverwriteTable(DataTable sourceTable, string tableName)
{
using (var destConn = new OleDbConnection(connectionstringA))
using (var destCmd = new OleDbCommand(tableName, destConn) { CommandType = CommandType.TableDirect })
using (var destDA = new OleDbDataAdapter(destCmd))
{
// Since we're using a single table, we can have the CommandBuilder
// generate the appropriate INSERT and DELETE SQL statements
using (var destCmdB = new OleDbCommandBuilder(destDA))
{
destCmdB.QuotePrefix = "["; // quote reserved column names
destCmdB.QuotePrefix = "]";
destDA.DeleteCommand = destCmdB.GetDeleteCommand();
destDA.InsertCommand = destCmdB.GetInsertCommand();
// Get rows from destination, and delete them
var destTable = new DataTable();
destDA.Fill(destTable);
foreach (DataRow dr in destTable.Rows)
{
dr.Delete();
}
destDA.Update(destTable);
// Set rows from source as Added, so the DataAdapter will insert them
foreach (DataRow dr in sourceTable.Rows)
{
dr.SetAdded();
}
destDA.Update(sourceTable); // !!! Run-time error: Syntax error in FROM clause. !!!
}
}
}
再一次,它不起作用。如果您需要其他信息,请与我们联系。
答案 0 :(得分:1)
我感觉你并没有真正想要整个DataTable / DataRow。您会看到,在数据库中,您并不真正使用表 - 而是使用行。如果要用TableA的行“覆盖”TableB,首先要删除TableB中的所有行,然后插入TableA中所有行的副本。
假设目标表已经存在,您可以通过从1个源填充,然后将行设置为“已添加”来执行插入。然后,DataAdapter将为每个添加的行运行SQL插入命令。
static void CopyTable(string sourceConnectionString, string destinationConnectionString, string tableName) {
// Get rows from source
var sourceTable = new DataTable();
using (var sourceConn = new OleDbConnection(sourceConnectionString))
using (var sourceCmd = new OleDbCommand(tableName, sourceConn) { CommandType = CommandType.TableDirect })
using (var sourceDA = new OleDbDataAdapter(sourceCmd)) {
sourceDA.Fill(sourceTable);
}
OverwriteTable(sourceTable, destinationConnectionString, tableName);
}
static void OverwriteTable(DataTable sourceTable, string destinationConnectionString, string tableName) {
using (var destConn = new OleDbConnection(destinationConnectionString))
using (var destCmd = new OleDbCommand(tableName, destConn) { CommandType = CommandType.TableDirect })
using (var destDA = new OleDbDataAdapter(destCmd)) {
// Since we're using a single table, we can have the CommandBuilder
// generate the appropriate INSERT and DELETE SQL statements
using (var destCmdB = new OleDbCommandBuilder(destDA)) {
destCmdB.QuotePrefix = "["; // quote reserved column names
destCmdB.QuoteSuffix = "]";
destDA.DeleteCommand = destCmdB.GetDeleteCommand();
destDA.InsertCommand = destCmdB.GetInsertCommand();
// Get rows from destination, and delete them
var destTable = new DataTable();
destDA.Fill(destTable);
foreach (DataRow dr in destTable.Rows) {
dr.Delete();
}
destDA.Update(destTable);
// Set rows from source as Added, so the DataAdapter will insert them
foreach (DataRow dr in sourceTable.Rows) {
dr.SetAdded();
}
destDA.Update(sourceTable);
}
}
}
编辑:将OverwriteTable拆分为另一种方法以容纳内存数据表。还为您保留的Year和Month列名称生成的Sql语句添加了引号。已将fixed的bendewey移至{{3}}处理。
答案 1 :(得分:1)
尝试替换
using (var destCmdB = new OleDbCommandBuilder(destDA))
{
destDA.DeleteCommand = destCmdB.GetDeleteCommand();
destDA.InsertCommand = destCmdB.GetInsertCommand();
}
与
destDA.InsertCommand = new OleDbCommand("INSERT INTO `AdminUsers` (`UserName`, `Password`) VALUES (?, ?)");
destDA.DeleteCommand = new OleDbCommand("DELETE FROM `AdminUsers` WHERE (`ID` = ?)");
destDA.UpdateCommand = new OldDbCommand("UPDATE `AdminUsers` SET `UserName` = ?, `Password` = ? WHERE (`ID` = ?)");
查询对您的表结构有效。
答案 2 :(得分:1)
@Mark Brackett真的很接近你得到no DeleteCommand的原因是因为OleDbCommandBuilder正在处理所以移动那个支架你应该是好的。
static void CopyTable(string sourceConnectionString, string destinationConnectionString, string tableName)
{
// Get rows from source
var sourceTable = new DataTable();
using (var sourceConn = new OleDbConnection(sourceConnectionString))
using (var sourceCmd = new OleDbCommand(tableName, sourceConn) {CommandType = CommandType.TableDirect})
using (var sourceDA = new OleDbDataAdapter(sourceCmd))
{
sourceDA.Fill(sourceTable);
}
using (var destConn = new OleDbConnection(destinationConnectionString))
using (var destCmd = new OleDbCommand(tableName, destConn) {CommandType = CommandType.TableDirect})
using (var destDA = new OleDbDataAdapter(destCmd))
{
// Since we're using a single table, we can have the CommandBuilder
// generate the appropriate INSERT and DELETE SQL statements
using (var destCmdB = new OleDbCommandBuilder(destDA))
{
destDA.DeleteCommand = destCmdB.GetDeleteCommand();
destDA.InsertCommand = destCmdB.GetInsertCommand();
// Get rows from destination, and delete them
var destTable = new DataTable();
destDA.Fill(destTable);
foreach (DataRow dr in destTable.Rows)
{
dr.Delete();
}
destDA.Update(destTable);
// Set rows from source as Added, so the DataAdapter will insert them
foreach (DataRow dr in sourceTable.Rows)
{
dr.SetAdded();
}
destDA.Update(sourceTable);
}
}
尝试此异常代码
static public void InitiateCopyProcessA()
{
DataSet tablesA;
tablesA = DatabaseHandling.getDataSetA();
int i = 0;
string tableName = "";
try
{
foreach (DataTable table in tablesA.Tables)
{
tableName = table.TableName; // for debugging the exception
CopyTable(connectionstringA, connectionstringB, table.TableName);
}
}
catch(Exception ex)
{
throw new Exception("Error updating " + tableName, ex);
}
}
尝试更改
// Set rows from source as Added, so the DataAdapter will insert them
foreach (DataRow dr in sourceTable.Rows)
{
dr.SetAdded();
}
到
// only add the first row.
sourceTable.Rows[0].SetAdded()
我很想知道它只是一行;抛出错误或是否是查询。我的想法是其中一行有一个时髦的价值