简单数据导出






3.59/5 (7投票s)
使用相同的表(SQL Server)将数据从数据库 a 简单导出到数据库 b。
引言
BImport 是一个简单的控制台应用程序,它将数据从数据库“a”中的一组表导出到数据库“b”中一组相同的表。
背景
我的懒惰又一次占了上风。我一直在开发一个应用程序,其中拥有实时数据进行工作而无需实际使用实时数据库非常有用。此程序允许我使用实时数据库中的当前数据更新我的开发数据库,而无需启动 SQL Server:我只需在 Explorer 中双击 EXE,然后,就完成了。简单。
使用 BImport
BImport 有两个部分
- 填充 *config* 文件,以便 BImport 知道要去哪里以及做什么。
- 该程序的精髓(假设您在 *config* 文件中提供了正确的详细信息)
- 循环遍历 *config* 文件 `appSettings` 部分中的每个键,然后
- 从源数据库中将数据加载到 `DataTable` 中。
- 打开与目标数据库的连接。
- 如果源 `DataTable` 有行...
- 截断目标表。
- 创建 `StringBuilders` 来存储
- INSERT 语句
- 字段列表
- 参数
- 最后,对于找到的每一行数据,执行一个 INSERT 语句。
这是一个示例 *App.config*,在程序编译后,它将被重命名为 *BImport.exe.config*,并将与 *BImport.exe* 放在同一个文件夹中。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<!-- Require source and target connection strings -->
<add name="SOURCE" connectionString="Persist Security Info=True;
User ID={USER_ID};PASSWORD={PASSWORD};Data Source={DATA_SOURCE};
Initial Catalog={INITIAL_CATALOG};"
providerName="Sql.Data.SqlClient" />
<add name="TARGET" connectionString="Persist Security Info=True;
User Id={USER_ID};Password={PASSWORD};Data Source={DATA_SOURCE};
Initial Catalog={INITIAL_CATALOG};"
providerName="Sql.Data.SqlClient" />
</connectionStrings>
<appSettings>
<!-- Tables that require 'set identity_insert [tablename] on'
should set value to true -->
<add key="Table1" value="true" />
<add key="Table2" value="true" />
<add key="Table3" value="false" />
<add key="Table4" value="true" />
</appSettings>
</configuration>
配置文件的组成部分有两个;第一个告诉 BImport 源数据库和目标数据库的连接字符串;第二个,需要复制数据的表的列表。请注意,您可以将每个表标记为需要使用 'set identity_insert [tableName] on
',如果这是必需的。原因是为了让您可以决定要复制哪些表:就我而言,我不必复制任何引用表,那么为什么还要费事呢?
获取表名
我想要一种非常快速、粗糙的方法来从 *config* 文件中获取数据,而无需考虑同一个键下有多个值。您需要确保已添加对 `System.Configuration` 的引用,然后就像这样简单:
foreach (string value in ConfigurationManager.AppSettings)
{
// Get the name of the table.
string tableName = value.ToString();
...
就是这样:如果我想要实际值,我可以执行 `ConfigurationManager.AppSettings[value]`,这在此情况下会给我一个表示是否使用 `identity_insert` 的 bool
。
现在我已经有了表名,我可以逐个处理它们。
使用一个辅助方法,我将源数据加载到一个 `DataTable` 中,然后仅当有要处理的行时,才为该表继续处理。
如果存在行,我将使用另一个辅助方法来首先确定我是否应使用 `identity_insert`,然后截断表,之后再插入源数据。
然后,我们可以遍历 `DataTable` 列并开始构建 INSERT 语句。
foreach (DataColumn dataColumn in dataTable.Columns)
{
fields.Append(dataColumn.ColumnName);
parameters.Append("@" + dataColumn.ColumnName.ToLower
(CultureInfo.InvariantCulture));
...
然后,循环遍历每个表的所有 `DataTable` 行,将值添加到参数中,然后执行查询。搞定!
foreach (DataRow dataRow in dataTable.Rows)
{
SqlCommand command = new SqlCommand(sql.ToString(), connection);
foreach (DataColumn dataColumn in dataTable.Columns)
{
command.Parameters.AddWithValue("@" +
dataColumn.ColumnName.ToLower(CultureInfo.InvariantCulture),
dataRow[dataColumn.ColumnName]);
}
...
然后
command.ExecuteNonQuery();
请注意,网络上有很多上面代码的示例,所以请随意植入您觉得更舒服的任何示例;不过,这似乎是一种简单明了的完成任务的方式。
注意:我只使用了此功能处理了 10 个表,其中最大的表大约有 2000 行,并且没有对更多表和更大的数据集进行测试:您需要自己确认该程序能否在及时有效的情况下处理更多表/更大的数据量。
最后,控制台将显示导出的行数。就是这样。完成。按任意键并使用数据。
结论
虽然这可以通过多种方式完成,但它在我目前的情况下效果很好;也许,可以将其包装在一个事务中,并且肯定可以受益于一些合适的异常处理,但这取决于您:目前,对我来说,它效果很好,并且每次都能完成它的工作。
BImport 是一个用于简单任务的简单应用程序,我也以此方式进行了编码:撰写这篇文章花费的时间更长!
历史
- 版本 1.0 - 2008 年 10 月 9 日
这基本上是第一个也是最后一个版本:这是一个微不足道的应用程序,它只执行一项简单的任务:如果您看到可以进行有用的改进的地方,请告诉我,我将更新文章并承认您的贡献。
版权所有 © 2008, Mark Merrens。