在软件开发过程中,经常需要将生产环境的数据迁移到测试环境中,以便测试人员能够使用实际数据量进行测试。本文将介绍如何使用SqlBulkCopy工具进行数据迁移,以及如何通过C#实现一个简单的数据迁移工具。
数据迁移工具可以帮助将生产环境的数据轻松迁移到测试环境中。使用SqlBulkCopy工具,可以快速地将大量数据迁移到目标数据库。SqlBulkCopy是ADO.NET2.0提供的一个托管类,它类似于BCP工具,但使用起来更加方便。
SqlBulkCopy工具支持SQL Server 2005和SQL Server 2000。它具有以下特点:
本文介绍的数据迁移工具是一个C#Windows Forms项目。项目非常简单,一个Windows表单完成了所有的工作。它使用BackgroundWorker组件来报告进度。源和目标连接定义在应用程序配置文件中。如果在删除或加载数据时发生任何异常,应用程序会记录异常并继续处理下一个表。
数据迁移工具主要包括两个主要功能:DeleteData和LoadData。
DeleteData功能主要完成以下任务:
private void DeleteData()
{
using (SqlConnection conn = new SqlConnection(strDestConn))
{
conn.Open();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandTimeout = 0;
if (ds != null && ds.Tables[0].Rows.Count > 0)
{
// 禁用所有表的约束
foreach (DataRow dr in ds.Tables[0].Rows)
{
cmd.CommandText = "ALTER TABLE [" + dr["TABLE_SCHEMA"].ToString() + "].[" + dr["TABLE_NAME"].ToString() + "] NOCHECK CONSTRAINT ALL";
cmd.CommandText += "ALTER TABLE [" + dr["TABLE_SCHEMA"].ToString() + "].[" + dr["TABLE_NAME"].ToString() + "] DISABLE TRIGGER ALL";
cmd.ExecuteNonQuery();
}
// 删除选定表中的数据并记录结果
string strLogFile = "DeleteLog" + DateTime.Now.ToString("MMddyyyyHHmm") + ".txt";
using (StreamWriter sw = new StreamWriter(strLogFile, false))
{
sw.AutoFlush = true;
foreach (object dr in lstInclude.Items)
{
try
{
cmd.CommandText = "SELECT OBJECTPROPERTY (object_id('" + dr.ToString() + "'),'TableHasForeignRef')";
int intref = Convert.ToInt32(cmd.ExecuteScalar());
if (intref == 1)
cmd.CommandText = "DELETE FROM " + dr.ToString();
else
cmd.CommandText = "TRUNCATE TABLE " + dr.ToString();
cmd.ExecuteNonQuery();
sw.WriteLine("Data deleted successfully from " + dr.ToString() + " at " + DateTime.Now.ToString());
sw.WriteLine();
}
catch (Exception ex)
{
sw.WriteLine("Error while deleting data in table " + dr.ToString() + ".Error is " + ex.Message);
sw.WriteLine();
}
}
}
// 启用所有表的约束
foreach (DataRow dr in ds.Tables[0].Rows)
{
cmd.CommandText = "ALTER TABLE [" + dr["TABLE_SCHEMA"].ToString() + "].[" + dr["TABLE_NAME"].ToString() + "] CHECK CONSTRAINT ALL";
cmd.CommandText += "ALTER TABLE [" + dr["TABLE_SCHEMA"].ToString() + "].[" + dr["TABLE_NAME"].ToString() + "] ENABLE TRIGGER ALL";
cmd.ExecuteNonQuery();
}
}
}
}
private void LoadData(string pSourceConn, string pDestConn, string pTable)
{
using (SqlConnection srcConn = new SqlConnection(pSourceConn))
{
string[] strTable = pTable.Split('.');
// 从源表中获取数据
srcConn.Open();
SqlCommand srcCommand = new SqlCommand("SELECT * FROM " + pTable, srcConn);
srcCommand.CommandTimeout = 0;
SqlDataReader sqldr = srcCommand.ExecuteReader();
SqlBulkCopy sqlbcp = new SqlBulkCopy(pDestConn, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.TableLock);
// 映射列
SqlConnection destConn = new SqlConnection(pDestConn);
destConn.Open();
SqlCommand cmd1 = new SqlCommand("SELECT COLUMN_NAME, COLUMNPROPERTY(OBJECT_ID('" + strTable[0] + "." + strTable[1] + "'),COLUMN_NAME,'IsComputed')AS 'IsComputed' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '" + strTable[0] + "' AND TABLE_NAME = '" + strTable[1] + "'", destConn);
SqlDataReader drcolumns = cmd1.ExecuteReader();
while (drcolumns.Read())
{
if (drcolumns.GetInt32(1) != 1)
sqlbcp.ColumnMappings.Add(drcolumns.GetString(0), drcolumns.GetString(0));
}
drcolumns.Close();
// 加载数据
sqlbcp.BulkCopyTimeout = 0;
sqlbcp.DestinationTableName = pTable;
sqlbcp.WriteToServer(sqldr);
sqldr.Close();
}
}