私が取り組んでいる私のプロジェクトはほぼ終了しました。.MDB ファイルを読み込んで、DataGrid にコンテンツを表示し、DataGrid でこれらの変更を取得して .MDB ファイルに保存しようとしています。また、ある .MDB ファイルからテーブルを取得して別の .MDB ファイルに保存できる関数も作成します。もちろん、変更を .MDB ファイルに保存する方法がわからない場合は、これを行うことはできません。
Google を広範囲に調査しましたが、私の質問に対する回答はありません。私は自分自身をこの特定のトピックの初心者だと考えているので、答えを複雑にしすぎないでください - .MDB ファイルを編集する最も簡単な方法が必要です! プログラミング例を教えてください。
- 既に DataGrid への接続を確立しているとします。Datagrid によって行われた変更を取得するにはどうすればよいですか? これは答えるのに十分簡単だと確信しています。
- 次に、このデータテーブルを取得し、元のデータセットに挿入し、そのデータセットを取得して .MDB ファイルを書き換える方法を知る必要があります。(変更されたテーブルのみを挿入する方法があれば、それをお勧めします。)
事前に感謝します。さらに情報が必要な場合はお知らせください。これはおそらく、このトピックについて私が尋ねなければならない最後のことです...神に感謝します.
編集:
私が使用している .mdb は、Microsoft Access データベースです。(複数の .mdb ファイルがあることさえ知りませんでした)
streamwriter などを使用して .MDB ファイルに直接書き込めないことはわかっていますが、DataSet 情報が既に含まれている .MDB ファイルを生成する方法はありますか? または、既に DataGrid にロードした .MDB ファイルにテーブルを追加する方法があります。方法があるはずです!
繰り返しますが、C# でプログラム的にこれを行う方法が必要です。
編集:
私のプロジェクトはかなり大きいですが、別のクラス ファイルを使用してすべてのデータベース接続を処理しています。私のデザインとソースが本当にずさんであることはわかっていますが、それで仕事は完了します。私は、インターネットで見つけた例と同じくらい上手です。
ここでは、別の形式で DataGrid に接続しているだけであることを思い出してください。Datagrid フォームから私のコードが必要な場合はお知らせください (ただし、なぜそれが必要なのかはわかりません)。DatabaseHandling.cs は、2 つの .MDB ファイルを処理します。そのため、そこに 2 つのデータセットが表示されます。最終的にこれを使用して、あるデータセットからテーブルを取得し、それらを別のデータセットに配置します。これらの値を .MDB ファイルに保存する方法を理解する必要があります。
とにかくこれを行うことはありますか?方法があるはずです...
編集:
私が調査して読んだことから...答えは私の目の前にあると思います。「Update()」コマンドを使用します。これは、実際にはこれを行う簡単な方法があることを再確認していますが、この更新コマンドの使用方法がまったくわからないという問題が残っています。
おそらく、次のように設定できます。
Oledb.OledbConnection cn = new Oledb.OledbConnection();
cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Staff.mdb";
Oledb.OledbCommand cmd = new Oledb.OledbCommand(cn);
cmd.CommandText = "INSERT INTO Customers (FirstName, LastName) VALUES (@FirstName, @LastName)";
それはできると思いますが、手動で何かを挿入したくありません。代わりにこれらの両方を実行したい:
- Datagrid で変更された情報を取得し、取得元の Access データベース ファイル (.mdb) を更新します。
- 別の Access データベース ファイル (.mdb) からテーブルを取得し、それらをセカンダリ Access データベース ファイル (.mdb) に置き換えることができる関数を作成します。どちらのファイルもまったく同じ構造を使用しますが、異なる情報が含まれています。
誰かがこれに対する答えを出してくれることを願っています...私のプロジェクトは完了しました。待っているのは1つの簡単な答えだけです。
よろしくお願いします。
編集:
わかりました...良いニュースです。.mdb ファイル自体を照会する方法を理解しました (と思います)。使用しようとしているSQLコマンドが原因で実行時エラーが発生するため、機能しないコードを次に示します。それは私の次の質問に私を連れて行きます。
DatabaseHandling.cs に追加された新しい関数コード:
static public void performSynchronization(string table, string tableTwoLocation)
{
OleDbCommand cmdCopyTables = new OleDbCommand("INSERT INTO" + table + "SELECT * FROM [MS Access;" + tableTwoLocation + ";].[" + table + "]"); // This query generates runtime error
cmdCopyTables.Connection = dataconnectionA;
dataconnectionA.Open();
cmdCopyTables.ExecuteNonQuery();
dataconnectionA.Close();
}
ご覧のとおり、実際に接続自体でクエリを実行することができました。これは、実際の Access .MDB ファイルであると思われます。私が言ったように、ファイルに対して実行した SQL クエリは機能せず、使用すると実行時エラーが発生しました。
私が実行しようとしているコマンドは、.MDB ファイルからテーブルを取得し、別の .MDB ファイルの同じタイプのテーブルを上書きすることになっています。上記で試みた SQL コマンドは、.mdb ファイルからテーブルを直接取得し、別のファイルに直接配置しようとしましたが、これは私がやりたいことではありません。.MDB ファイルからすべての情報を取得したい - テーブルを Datatable に入れ、すべての Datatables を Dataset に追加します (これを行いました)。これを 2 つの .MDB ファイルに対して行います。2 つのデータセットを取得したら、各データセットから特定のテーブルを取り出し、次のように各ファイルに追加します。
- DataSetA >>>>----- [テーブル追加(上書き)] ----->>>> DataSetB
- DataSetB >>>>----- [テーブルを追加 (上書き)] ----->>>> DataSetA
これらの各データセットを取得し、元の各 Access .MDB ファイルに戻します。基本的に両方のデータベースの同期を維持します。
だから私の質問は、改訂されたものです:
- 同じ名前の既存のテーブルを上書きして .MDB ファイルにテーブルを追加する SQL クエリを作成するにはどうすればよいですか。クエリは、変数を追加したいテーブル名に置き換える配列を使用して、実行時に動的に作成できる必要があります。
- Datagrid によって DataTable に加えられた変更を取得し、それらを DataTable (または DataSet) に戻して、.MDB ファイルに送信できるようにするにはどうすればよいですか?
私は自分の問題をうまく説明していないと思うので、できる限り詳しく説明しようとしました。さて、この質問はあまりにも長くなりすぎました。これをもっとうまく説明できればいいのにと思います。:[
編集:
以下のユーザーのおかげで、私はほぼ修正を見つけたと思います - キーワードほぼ. 以下は、更新された DatabaseHandling.cs コードです。「データ型が一致しません」という実行時エラーが発生します。これらのテーブルをまったく同じセットアップで別のデータベースにコピーしようとしていることを考えると、それがどのように可能になるかわかりません。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
using System.Data;
using System.IO;
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!");
}
if (addtoDataSet == true)
{
datasetA.Tables.Add(datatableA);
Logging.updateLog("Added DataTableA: " + datatableA.TableName.ToString() + " Successfully!");
}
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!");
}
if (addtoDataSet == true)
{
datasetB.Tables.Add(datatableB);
Logging.updateLog("Added DataTableB: " + datatableB.TableName.ToString() + " Successfully!");
}
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...");
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);
}
}
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);
}
}
}
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)
{
CopyTable(table, connectionstringB);
}
}
public static void CopyTable(DataTable table, string connectionStringB)
{
var connectionB = new OleDbConnection(connectionStringB);
foreach (DataRow row in table.Rows)
{
InsertRow(row, table.Columns, table.TableName, connectionB);
}
}
public static void InsertRow(DataRow row, DataColumnCollection columns, string table, OleDbConnection connection)
{
var columnNames = new List<string>();
var values = new List<string>();
for (int i = 0; i < columns.Count; i++)
{
columnNames.Add("[" + columns[i].ColumnName + "]");
values.Add("'" + row[i].ToString().Replace("'", "''") + "'");
}
string sql = string.Format("INSERT INTO {0} ({1}) VALUES ({2})",
table,
string.Join(", ", columnNames.ToArray()),
string.Join(", ", values.ToArray())
);
ExecuteNonQuery(sql, connection);
}
public static void ExecuteNonQuery(string sql, OleDbConnection conn)
{
if (conn == null)
throw new ArgumentNullException("conn");
ConnectionState prevState = ConnectionState.Closed;
var command = new OleDbCommand(sql, conn);
try
{
prevState = conn.State;
if (prevState != ConnectionState.Open)
conn.Open();
command.ExecuteNonQuery(); // !!! Runtime-Error: Data type mismatch in criteria expression. !!!
}
finally
{
if (conn.State != ConnectionState.Closed
&& prevState != ConnectionState.Open)
conn.Close();
}
}
}
}
このエラーが発生するのはなぜですか? 両方のテーブルはまったく同じです。私は何を間違っていますか?最悪の場合、まったく同じ構造のテーブルを別の値で挿入する前に、別の Access .MDB ファイルのテーブルを削除するにはどうすればよいですか?
男私はこれを理解できたらいいのに...
編集:
よし、だいぶ離れた。私の質問は新しいものに変化したため、個別に質問する価値があります。開いた接続に対して直接クエリを実行する方法がわかったので、質問に答えてもらいました。皆さん、ありがとうございました!