C# 在数据库之间复制表
假设我想将所有表及其完整数据从一个数据库复制到另一个数据库,而不具体了解有关它们的详细信息(列计数、数据类型…)。用户将向其数据库输入一个连接字符串,其中的所有数据将复制到一个内部数据库。 我试图通过使用SqlConnection和编写直接T-SQL查询来实现它,并设法编写了一个脚本,在内部数据库中创建具有正确列的空表:C# 在数据库之间复制表,c#,sql-server,database,sqlconnection,smo,C#,Sql Server,Database,Sqlconnection,Smo,假设我想将所有表及其完整数据从一个数据库复制到另一个数据库,而不具体了解有关它们的详细信息(列计数、数据类型…)。用户将向其数据库输入一个连接字符串,其中的所有数据将复制到一个内部数据库。 我试图通过使用SqlConnection和编写直接T-SQL查询来实现它,并设法编写了一个脚本,在内部数据库中创建具有正确列的空表: string createDestinationTableQuery = "create table " + schemaName + ".[" + tableName + "
string createDestinationTableQuery = "create table " + schemaName + ".[" + tableName + "](";
DataTable ColumnsDT = new DataTable();
string getTableColumnDataQuery = "SELECT * FROM "+originalDBName+".INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = N'" + tableName +"'";
SqlCommand getTableColumnDataCommand = new SqlCommand(getTableColumnDataQuery, originalCon);
SqlDataAdapter TableDA = new SqlDataAdapter(getTableColumnDataCommand);
TableDA.Fill(ColumnsDT);
for (int x = 0; x < ColumnsDT.Rows.Count; x++)
{
createDestinationTableQuery += "[" + ColumnsDT.Rows[x].ItemArray[3].ToString() + "] " + "[" + ColumnsDT.Rows[x].ItemArray[7].ToString() + "], ";
}
createDestinationTableQuery = createDestinationTableQuery.Remove(createDestinationTableQuery.Length - 2);
createDestinationTableQuery += " )";
SqlCommand createDestinationTableCommand = new SqlCommand(createDestinationTableQuery, destinationCon);
createDestinationTableCommand.ExecuteNonQuery();
Console.WriteLine("Table " + schemaName + "." + tableName + " created succesfully!");
string createDestinationTableQuery=“create table”+schemaName+”[“+tableName+”](”;
DataTable ColumnsDT=新DataTable();
string getTableColumnDataQuery=“SELECT*FROM”+originalDBName+”。信息\u SCHEMA.COLUMNS,其中TABLE\u NAME=N'”+tableName+“”;
SqlCommand getTableColumnDataCommand=新的SqlCommand(getTableColumnDataQuery,originalCon);
SqlDataAdapter TableDA=新的SqlDataAdapter(getTableColumnDataCommand);
表A.填充(第SDT列);
对于(int x=0;x
但是,由于以下代码根本无法工作,因此我正在努力进行数据插入:
DataTable dataTable = new DataTable();
string getTableDataquery = "select * from " + originalTableWithSchema;
SqlCommand getTableDataCommand = new SqlCommand(getTableDataquery, originalCon);
SqlDataAdapter da = new SqlDataAdapter(getTableDataCommand);
da.Fill(dataTable);
for (int x = 0; x < dataTable.Rows.Count; x++)
{
string insertQuery = "insert into " + schemaName + ".["+tableName+"](" ;
string values = "VALUES(";
for (int y = 0; y < dataTable.Columns.Count; y++)
{
insertQuery += dataTable.Columns[y].ColumnName + ", ";
values += dataTable.Rows[x].ItemArray[y].ToString() + ", ";
}
insertQuery = insertQuery.Remove(insertQuery.Length - 2);
insertQuery += " )";
values = values.Remove(values.Length - 2);
values += " )";
insertQuery += " " + values;
SqlCommand insertCommand = new SqlCommand(insertQuery, destinationCon);
insertCommand.ExecuteNonQuery();
}
da.Dispose();
DataTable=newdatatable();
字符串getTableDataquery=“select*from”+originalTableWithSchema;
SqlCommand getTableDataCommand=新的SqlCommand(getTableDataquery,originalCon);
SqlDataAdapter da=新的SqlDataAdapter(getTableDataCommand);
da.填充(数据表);
对于(int x=0;x
如何正确实现此功能?我在考虑是否应该放弃所有的代码,改用SMO 如果您只希望复制数据(因为已经在创建结构),那么可以使用DataTable将数据保存在非dbms特定的结构中,并使用DataAdapter生成dbms特定的insert语句。下面是我不久前编写的将数据从Access复制到MySQL的代码摘录:
List<string> tableNames = new List<string>();
try
{
// Open connect to access db
sourceConn.Open();
// Build table names list from schema
foreach (DataRow row in sourceConn.GetSchema("Tables").Select("table_type = 'TABLE'"))
tableNames.Add(row["table_name"].ToString());
}
catch (Exception ex)
{
throw ex;
}
finally
{
if(sourceConn.State != ConnectionState.Closed)
sourceConn.Close();
}
foreach (string table in tableNames)
{
//Get all table data from Access
string query = string.Format("SELECT * FROM {0}", table);
DataTable accessTable = new DataTable(table);
try
{
sourceConn.Open();
System.Data.OleDb.OleDbCommand accessSqlCommand = new System.Data.OleDb.OleDbCommand(query, accessConn);
System.Data.OleDb.OleDbDataReader reader = (System.Data.OleDb.OleDbDataReader)accessSqlCommand.ExecuteReader();
// Load all table data into accessTable
accessTable.Load(reader);
}
catch(Exception ex)
{
throw ex;
}
finally
{
if(sourceConn.State != ConnectionState.Closed)
sourceConn.Close();
}
// Import data into MySQL
accessTable.AcceptChanges();
// The table should be empty, so set everything as new rows (will be inserted)
foreach (DataRow row in accessTable.Rows)
row.SetAdded();
try
{
destConn.Open();
MySql.Data.MySqlClient.MySqlDataAdapter da = new MySql.Data.MySqlClient.MySqlDataAdapter(query, mySqlConn);
MySql.Data.MySqlClient.MySqlCommandBuilder cb = new MySql.Data.MySqlClient.MySqlCommandBuilder(da);
da.InsertCommand = cb.GetInsertCommand();
// Update the destination table 128 rows at a time
da.UpdateBatchSize = 128;
// Perform inserts (and capture row counts for output)
int insertCount = da.Update(accessTable);
}
catch (Exception ex)
{
throw ex;
}
finally
{
if(destConn.State != ConnectionState.Closed)
destConn.Close();
}
}
List tableNames=new List();
尝试
{
//打开连接以访问数据库
sourceConn.Open();
//从架构生成表名列表
foreach(sourceConn.GetSchema(“表”)中的数据行。选择(“表类型='table'))
tableNames.Add(行[“table_name”].ToString());
}
捕获(例外情况除外)
{
掷骰子;
}
最后
{
if(sourceConn.State!=ConnectionState.Closed)
sourceConn.Close();
}
foreach(表名中的字符串表)
{
//从Access获取所有表数据
字符串查询=string.Format(“从{0}中选择*表);
DataTable accessTable=新的DataTable(表);
尝试
{
sourceConn.Open();
System.Data.OleDb.OleDbCommand accessSqlCommand=new System.Data.OleDb.OleDbCommand(query,accessConn);
System.Data.OleDb.OleDbDataReader=(System.Data.OleDb.OleDbDataReader)accessSqlCommand.ExecuteReader();
//将所有表数据加载到accessTable中
加载(读卡器);
}
捕获(例外情况除外)
{
掷骰子;
}
最后
{
if(sourceConn.State!=ConnectionState.Closed)
sourceConn.Close();
}
//将数据导入MySQL
accessTable.AcceptChanges();
//该表应为空,因此将所有内容设置为新行(将插入)
foreach(accessTable.Rows中的DataRow行)
row.SetAdded();
尝试
{
destConn.Open();
MySql.Data.MySqlClient.MySqlDataAdapter da=new MySql.Data.MySqlClient.MySqlDataAdapter(查询,mySqlConn);
MySql.Data.MySqlClient.MySqlCommandBuilder cb=new MySql.Data.MySqlClient.MySqlCommandBuilder(da);
da.InsertCommand=cb.GetInsertCommand();
//一次更新目标表128行
da.UpdateBatchSize=128;
//执行插入(并捕获输出的行计数)
int insertCount=da.Update(accessTable);
}
捕获(例外情况除外)
{
掷骰子;
}
最后
{
if(destConn.State!=ConnectionState.Closed)
destConn.Close();
}
}
这当然可以更有效,但我写它是为了快速转换。此外,由于这是复制和粘贴的,您可能需要调整它。希望有帮助。使用链接服务器可能值得考虑。在目标服务器中定义链接服务器后,可以使用
SELECT…INTO
语句创建一个表并自动填充数据
在目标服务器数据库中执行的查询:
SELECT * INTO NewTableName FROM
SourceServername.SourceDatabasename.dbo.SourceTableName
`代码根本不起作用:`它是什么意思?你调试代码了吗?有什么错误吗?
try…catch…throw
对我来说很奇怪。有什么理由用这个吗?@UweKeim我同意。我怀疑他们正在使用反模式,所以他们总是关闭连接。OP-更好的方法是将连接包装在USING语句中。@SeanLange或至少使用try…finally
,wi