2015-01-26

  软件开发中,经常涉及到不同数据库(包括不同产品的不同版本)之间的数据结构与数据的导入导出。处理过程中会遇到很多问题,尤为突出重要的一个问题就是主从表之间,从表有外检约束,从而导致部分数据无法导入。

 

  情景一、同一数据库产品,相同版本

  此种情况下源数据库与目标数据库的数据结构与数据的导入导出非常简单。

方法1:备份源数据库,恢复到目标数据库即完成。

方法2:使用SQL Sever数据库自带的【复制数据库】功能或者【导入数据】功能按照向导操作即可。

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server

 

  情景二、同一数据库产品,不同版本

          情景1、源数据库版本低,目标数据库版本高

        此种情况处理方式同情景一。

          情景2、源数据库版本高,目标数据库版本低

        由于目标数据库版本低于源数据库,源数据库中产生的脚本架构无法兼容低版本,所以不能通过直接备份还原的方式来操作。

 

  本文以SQL Server2008R2数据库为数据源、SQL2008 Express为目标数据库为例主要解决主从表之间,从表有外检约束时,数据导入失败的问题。操作过程分为以下几个步骤:

  步骤1:从源数据库生成数据结构脚本【不包表含外键关系】

 

 

  在数据源188连接上,右键点击源数据库》【任务】》【生成脚本】

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_02

弹出“生成和发布脚本”

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_03

点击【下一步】按钮,弹出“简介”窗口

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_04

点击【下一步】按钮,弹出“设置脚本编写选项”

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_05

点击【高级】按钮,弹出具体设置窗口【此步骤非常重要

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_06

将“编写外键脚本”的值设置为false,意思是这一步骤生成的数据结构脚本中不包含表之间的外键关系。其他选项根据实际情况设置。

点击【确定】按钮,生成脚本,入下图。

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_07

 将脚本另存为“OriginalDataStructureWithoutFK.sql”。

 

  步骤2:导入数据结构脚本至目标数据库

 

 

  在目标服务器上新建目标数据库,命名同源数据库名(其他命名也可以)。

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_08

选中新建的数据库,打开步骤一中保存的”OriginalDataStructureWithoutFK.sql“脚本文件,运行该文件,运行成功后,目标数据库中成功创建了表、视图、存储过程、自定义函数,如下图

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_09SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_10

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_11SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_12

 

 

  步骤3:从源数据库创建数据脚本

 

 

  此步骤中,借助第三方数据库插件SqlAssistant,其拥有强大的数据库扩展功能,本文不做详细介绍。可以到SqlAssistant官网了解更多http://www.softtreetech.com/isql.htm

选中源数据库,点击右键,【Sql Assistant】》【Scripts Data】

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_13

 

弹出”Table Data Export” 导出Table数据窗口

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_14

默认选中源数据库与所有的表。点击【Export】按钮,生成数据脚本至【新建查询窗口】中

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_15

保存该数据脚本为“OriginalData.sql”。

  步骤4:导入数据脚本至目标数据库

 

 

对于表中主键或者其他设置为int类型,且设置自增长类型的列,需要做以下处理:

SET IDENTITY_INSERT dbo.T_ACL_User ON ;

一般字段如果是identity的,比如定义的时候nameid identity(1,1)就是说从1开始增长,每次加1,那么插入一条记录nameid字段是不需要手动赋值(一般也不允许)。那么有时候需要插入自定义值的时候,就设置set identity_insert on;就可以手动插入了。操作完数据插入后,再将其关闭。

 

选中目标数据库,并打开步骤3中保存的“OriginalData.sql”数据脚本,运行之,成功后,查看数据表

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_16

查询结果可以看出已经成功导入数据。

设置 SET IDENTITY_INSERT dbo.T_ACL_User Off ;

 

  步骤5:从源数据库生成仅包含表外键关系的数据结构脚本

 

 

  步骤与步骤1大致相同,最后一步设置相反

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_17

红色框内,将“编写外键脚本”设置为True,其他选项与步骤1中设置相反。点击"确定"按钮,生成脚本,另存为“OriginalDataStructureOnlyWithFK.sql”。

  步骤6:导入外键结构关系脚本至目标数据库

 

 

  选中目标数据库,打开步骤5中保存的“OriginalDataStructureOnlyWithFK.sql”脚本文件,运行之,运行成功后,查看表结构

SQL Server数据库中导入导出数据及结构时主外键关系的处理_SQL Server_18

外键已经成功创建。

 

成在管理,败在经验;嬴在选择,输在不学!  贵在坚持!

 

   

 个人作品

   

    1、BIMFace.Community.SDK.NET

     开源地址:https://gitee.com/NAlps/BIMFace.SDK

   

    2、ZCN.NET.Common

     开源地址:https://gitee.com/NAlps/zcn.net.common

 技术栈

   

 1、Visual Studio、.C#/.NET、.NET Core、MVC、Web API、RESTful API、gRPC、SignalR、Python

 2、jQuery、Vue.js、Bootstrap

 3、数据库:SQLServer、MySQL、PostgreSQL、Oracle、SQLite、Redis、MongoDB、ElasticSearch、TiDB、达梦DM、人大金仓、 神通、南大通用 GBase、华为 GaussDB 、腾讯 TDSQL 、阿里 PolarDB、蚂蚁金服 OceanBase、东软 OpenBASE、浪潮云溪数据库 ZNBase

 4、ORM:Dapper、Entity Framework、FreeSql、SqlSugar、分库分表、读写分离

 5、架构:领域驱动设计 DDD、ABP

 6、环境:跨平台、Windows、Linux(CentOS、麒麟、统信UOS、深度Linux)、maxOS、IIS、Nginx、Apach

 7、移动App:Android、IOS、HarmonyOS、微信、小程序、快应用、Xamarin、uni-app、MUI、Flutter、Framework7、Cordova、Ionic、React Native、Taro、NutUI、Smobiler

   

 云原生、微服务、Docker、CI/CD、DevOps、K8S;

 Dapr、RabbitMQ、Kafka、分布式、大数据、高并发、负载均衡、中间件、RPC、ELK;

 .NET + Docker + jenkins + Github + Harbor + K8S;作者:张传宁   微软MCP、系统架构设计师、系统集成项目管理工程师、科技部创新工程师。

          专注于微软.NET技术(.NET Core、Web、MVC、WinForm、WPF)、通用权限管理系统、工作流引擎、自动化项目(代码)生成器、SOA 、DDD、 云原生(Docker、微服务、DevOps、CI/CD);PDF、CAD、BIM 审图等研究与应用。

          多次参与电子政务、图书教育、生产制造等企业级大型项目研发与管理工作。

          熟悉中小企业软件开发过程:需求分析、架构设计、编码测试、实施部署、项目管理。通过技术与管理帮助中小企业快速化实现互联网技术全流程解决方案。

         


         

本文版权归作者有,欢迎转载,但未经作者同意必须保留此段声明,否则保留追究法律责任的权利。