C# ODBC.NETでテーブルを複製するサンプル

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();
        }
    }

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です