DataReaderで取得したフィールド名等の情報を本に、SQL文(DELETE文、INSETR文)を動的に作成して、テーブル内のデータコピーを行うサンプル。
CopyTableの引数としてテーブル名、プライマリキー名の配列、コピー元データベースのConnection、コピー先データベースのConnectionを与えて下さい。
class Program
{
static void Main(string[] args)
{
OdbcConnection srceConn = new OdbcConnection("Driver={SQL Server};Server=SV01;UID=example;PWD=;");
srceConn.Open();
OdbcConnection destConn = new OdbcConnection("Driver={SQL Server};Server=SV02;UID=example;PWD=;");
destConn.Open();
CopyTable("table_name", new string[] { "primary_key_1", "primary_key_2" }, srceConn, destConn);
Console.ReadKey();
}
static void CopyTable(string tableName, string[] keyNames, OdbcConnection srceConn, OdbcConnection destConn)
{
Console.WriteLine("Copying {0}", tableName);
StringBuilder insSql = null;
Dictionary<string, int> columnIndexs = new Dictionary<string, int>();
// DELETEコマンド文字列の生成
StringBuilder delSQL = new StringBuilder();
delSQL.Append(" DELETE ");
delSQL.Append(tableName);
delSQL.Append(" WHERE ");
bool isFirst = true;
foreach (var key in keyNames)
{
if (false == isFirst)
{
delSQL.Append(" AND ");
}
delSQL.Append(key);
delSQL.Append(" = ? ");
isFirst = false;
}
// トランザクション開始
var trans = destConn.BeginTransaction();
// 複製本のデータ読み出し
int recCnt = 0;
OdbcCommand selectCmd = new OdbcCommand("SELECT * FROM " + tableName, srceConn);
var rdr = selectCmd.ExecuteReader();
while (rdr.Read())
{
Console.Write("record {0}\r", recCnt++);
// フィールド位置検索用にインデックス作成
if (columnIndexs.Keys.Count == 0)
{
for (int i = 0; i < rdr.FieldCount; i++)
{
columnIndexs.Add(rdr.GetName(i), i);
}
}
// INSERTコマンド文字列の生成
if (insSql == null)
{
insSql = new StringBuilder();
insSql.Append(" INSERT INTO ");
insSql.Append(tableName);
insSql.Append(" ( ");
for (int i = 0; i < rdr.FieldCount; i++)
{
if (i > 0)
{
insSql.Append(",");
}
insSql.Append(rdr.GetName(i));
}
insSql.Append(" ) VALUES ( ");
for (int i = 0; i < rdr.FieldCount; i++)
{
if (i > 0)
{
insSql.Append(",");
}
insSql.Append("?");
}
insSql.Append(" ) ");
}
// DELETEコマンドのパラメータ設定と実行
int keyCnt = 0;
OdbcCommand delCmd = new OdbcCommand(delSQL.ToString(), destConn, trans);
foreach (var key in keyNames)
{
delCmd.Parameters.Add(new OdbcParameter("arg" + keyCnt.ToString("00"), rdr.GetValue(columnIndexs[key])));
}
delCmd.ExecuteNonQuery();
// INSERTコマンドのパラメータ設定と実行
keyCnt = 0;
OdbcCommand insCmd = new OdbcCommand(insSql.ToString(), destConn, trans);
for (int i = 0; i < rdr.FieldCount; i++)
{
insCmd.Parameters.Add(new OdbcParameter("arg" + keyCnt.ToString("00"), rdr.GetValue(i)));
}
insCmd.ExecuteNonQuery();
}
Console.WriteLine("{0} Records Copyed...", recCnt);
trans.Commit();
}
}