私は、C# を使用して DataTable 入力を取得し、それを SQL Server テーブルに書き込む最も効率的な方法を見つけることを検討するよう求められました。問題は、ソリューション全体で ODBC 接続を使用する必要があることです。これにより、sqlBulkCopy が除外されます。このソリューションは、SQL Server 2008 R2 までさかのぼるすべての SQL Server バージョンでも機能する必要があります。
次の SQL 構文を使用して、一度に 1000 行のバッチ挿入を使用するのが最善の方法だと考えています。
INSERT INTO dbo.Table1(Field1, Field2) SELECT Value1, Value2 UNION SELECT Value1, Value2
DataTable 入力に対応するテーブルが SQL Server に既に存在するかどうかを確認し、存在しない場合は作成するコードを既に作成しました。
INSERT ステートメント自体を作成するコードも作成しました。私が苦労しているのは、データ テーブルの行から SELECT ステートメントを動的に構築する方法です。行の値にアクセスして SELECT ステートメントを作成するにはどうすればよいですか? 値をシングル クォーテーション (') で囲む必要があるかどうかを判断するために、各列のデータ型も確認する必要があると思います。
これが私の現在のコードです:
public bool CopyDataTable(DataTable sourceTable, OdbcConnection targetConn, string targetTable)
{
OdbcTransaction tran = null;
string[] selectStatement = new string[sourceTable.Rows.Count];
// Check if targetTable exists, create it if it doesn't
if (!TableExists(targetConn, targetTable))
{
bool created = CreateTableFromDataTable(targetConn, sourceTable);
if (!created)
return false;
}
try
{
// Prepare insert statement based on sourceTable
string insertStatement = string.Format("INSERT INTO [dbo].[{0}] (", targetTable);
foreach (DataColumn dataColumn in sourceTable.Columns)
{
insertStatement += dataColumn + ",";
}
insertStatement += insertStatement.TrimEnd(',') + ") ";
// Open connection to target db
using (targetConn)
{
if (targetConn.State != ConnectionState.Open)
targetConn.Open();
tran = targetConn.BeginTransaction();
for (int i = 0; i < sourceTable.Rows.Count; i++)
{
DataRow row = sourceTable.Rows[i];
// Need to iterate through columns in row, getting values and data types and building a SELECT statement
selectStatement[i] = "SELECT ";
}
insertStatement += string.Join(" UNION ", selectStatement);
using (OdbcCommand cmd = new OdbcCommand(insertStatement, targetConn, tran))
{
cmd.ExecuteNonQuery();
}
tran.Commit();
return true;
}
}
catch
{
tran.Rollback();
return false;
}
}
アドバイスをいただければ幸いです。また、私が提案しているものよりも簡単なアプローチがあれば、その詳細は素晴らしいでしょう.