记一次数据迁移的全过程

编程入门 行业动态 更新时间:2024-10-20 16:23:56

记一次数据迁移的<a href=https://www.elefans.com/category/jswz/34/1769896.html style=全过程"/>

记一次数据迁移的全过程

背景

某大型项目的二期开发完成上线,需要初始化大量的数据源,并且第三方BPM系统提供的数据源也并非是完全按照我们所需要的格式、表结构给出的,所以需要做一次数据迁移。所用数据库为SqlServer,本次迁移思路可用于任何数据库间、表结构不一致的迁移

前提及要求

  1. 明确本地数据迁移的范围
  2. 数据迁移中数据保持一致性
  3. 业务表增加迁移数据标识,业务表迁移数据字段ISMOVE='Y'

逻辑

由第三方提供数据源,经过清洗、过滤、写入到自己的业务库、业务表

 实现

1.创建QY_Tables、Qy_Maping、Qy_FieldDic、Qy_ErrorMsg四张迁移设置表

--迁移表设置
CREATE TABLE QY_Tables
(ID        INT NOT NULL -- 主键
, Type      VARCHAR (255) NULL  -- 类型【试图、表,一般皆为表】
, Business  VARCHAR (255) NULL -- 业务模块
, TableName VARCHAR (255) NULL -- 表名中文
, TableCode VARCHAR (255) NULL -- 第三方提供的数据表表名【用于存储清洗后的数据】
, BPMTable  VARCHAR (255) NULL -- 从第三方数据库同步过来之后的数据源表名[用于第一次同步第三方数据源到自己的库中]
, BPMVIEW   VARCHAR (255) NULL -- 将第三方数据源表字段更换为中文所用试图,便于查看
, CostTable VARCHAR (255) NULL -- 自己的业务表
, Mark      VARCHAR (255) NULL -- 备注
, Doing     VARCHAR (255) NULL -- 是否同步
)--迁移字段设置表
--有可能QyTableFieldName字段在QyTableFieldCodeBPM中没有,那么设置QyDefaultValue默认值即可
--这个表,是设置我们所需要的业务字段,用于清洗数据使用
CREATE TABLE Qy_Maping
(Id                   INT IDENTITY NOT NULL --主键
, QyTableName          NVARCHAR (50) NULL -- 迁移表名
, QyTableFieldName     NVARCHAR (50) NULL -- 迁移字段中文名称
, QyTableFieldCode     NVARCHAR (50) NULL -- 迁移字段英文
, QyTableFieldCodeBPM  NVARCHAR (50) NULL -- 第三方迁移表字段英文
, QyRemark             NVARCHAR (200) NULL --字段备注
, QyPOPTYPE            NVARCHAR (200) NULL -- 下拉框字典,对应 Qy_FieldDic.POPTYPE
, QyPOPTYPEValueSouce  NVARCHAR (50) NULL --下拉框字段具体值,对应 Qy_FieldDic.TITLEVALUE
, QyDefaultValue       NVARCHAR (50) NULL -- 默认值
, QyRelaceNullValue    NVARCHAR (50) NULL -- 如果第三方字段为空,默认替代值
, QyTableFieldType     NVARCHAR (50) NULL -- 字段类型【'int'、'nvarchar'等】
, QyTableFieldDataType NVARCHAR (50) NULL -- 字段类型,一般如果是枚举值时不为空,其他为空
, QyIsNull             NVARCHAR (50) NULL -- 是否为null
, QyIsNullBPM          NVARCHAR (50) NULL -- 第三方数据源是否为null
, QyDeaultBPMValue     NVARCHAR (50) NULL -- 第三方数据源默认值
)
GO-- 字段字典枚举值
CREATE TABLE dbo.Qy_FieldDic
(ID                INT IDENTITY NOT NULL -- 主键
, POPUPLSTELEMENTID INT NULL -- 对应自己业务系统中已有的字段枚举值表ID,没有填0
, TITLECN           NVARCHAR (50) NULL -- 中文含义
, TITLEVALUE        NVARCHAR (50) NULL -- 编码
, POPTYPE           NVARCHAR (50) NULL -- 枚举类型
, BPMCODE           NVARCHAR (50) NULL -- 第三方数据源值编码
, BPMCLOUMN         NVARCHAR (50) NULL -- 第三方数据源值对应的数据源列
, BPMTABLE          NVARCHAR (50) NULL -- 所在迁移表表名
, CONSTRAINT PK_Qy_FieldDic PRIMARY KEY (ID)
)
GO--错误日志表,主要用于迁移失败的日志记录,可根据自己的业务自由扩展字段
CREATE TABLE dbo.Qy_ErrorMsg
(Id                INT IDENTITY NOT NULL -- 主键
, FromTableName     NVARCHAR (50) NULL -- 来源表
, ToTableName       NVARCHAR (50) NULL -- 业务目标表
, ErrorMsg          NVARCHAR (max) NULL -- 错误信息
, ErrorSqlCmd NVARCHAR (max) NULL -- 执行的sql语句
, CONSTRAINT PK_Qy_ErrorMsg PRIMARY KEY (Id)
)
GO

2.BPM仅仅是提供了数据源的试图,并且数据源还在他们系统中,由于迁移量较大,所以先通过数据库桥接的形式,把他们提供的所有的数据源迁移到自己数据库的中间库[中间表];通过VIEW_SQL_Proc_BPM_IN试图批量生成同步数据到自己中间库的sql语句,也可以将查询到的sql进一步分装成存储过程Proc_IN_BPM,这样执行起来同步更加方便。

create VIEW VIEW_SQL_Proc_BPM_IN AS
SELECT 
'IF OBJECT_ID (''dbo.'+BPMTable+''') IS NOT NULL DROP TABLE dbo.'+BPMTable+';' AS SQL
FROM VIEW_QY_Tables
WHERE BPMTable <> ''
UNION ALLSELECT 
'SELECT * INTO '+BPMTable+' from openquery(BPM, ''select * from sgbpm_prd.'+BPMTable + ''') TEMP;' AS SQL
FROM VIEW_QY_Tables
WHERE BPMTable <> ''
GO--中间如果有报错,根据实际情况更改下sql的查询方式即可
CREATE proc [dbo].[Proc_IN_BPM]
as
begin
--DROP TABLE bpm_fkjl_heyue_view;
DROP TABLE 	bpm_QY_BudgetMapKM_view	;
DROP TABLE 	bpm_QY_BudgetMapZT_view	;
DROP TABLE 	bpm_QY_BudgetZT_view	;
DROP TABLE 	bpm_QY_Company_view	;
DROP TABLE 	bpm_QY_ContractAppendices_view	;
DROP TABLE 	bpm_QY_ContractBasic_view	;
DROP TABLE 	bpm_QY_ContractCost_view	;
DROP TABLE 	bpm_QY_ContractMatter_view	;
DROP TABLE 	bpm_QY_ContractParty_view	;
DROP TABLE 	bpm_QY_ContractPayment_view	;
DROP TABLE 	bpm_QY_ContractType_view	;
DROP TABLE 	bpm_QY_Department_view	;
DROP TABLE 	bpm_QY_Legal_view	;
DROP TABLE 	bpm_QY_LX_Basic_view	;
DROP TABLE 	bpm_QY_LX_File_view	;
DROP TABLE 	bpm_QY_LX_Release_view	;
DROP TABLE 	bpm_QY_LX_Subject_view	;
DROP TABLE 	bpm_QY_Person_view	;
DROP TABLE 	bpm_QY_Project_view	;
DROP TABLE 	bpm_QY_Provision_gys_view	;
DROP TABLE 	bpm_QY_Provision_jtmx_view	;
DROP TABLE 	bpm_QY_Provision_view	;
DROP TABLE 	bpm_QY_Subject_view	;
DROP TABLE 	bpm_QY_YS_File_view	;
DROP TABLE 	bpm_QY_YS_PayPlan_view	;
DROP TABLE 	bpm_QY_YS_Settlement_view	;
DROP TABLE 	bpm_QY_YS_Subject_view	;
DROP TABLE 	bpm_QY_YS_view	;--DROP TABLE 	BPM_JITICHONGXIAO_NEW_VIEW	;
--DROP TABLE 	BPM_JITICHONGXIAOMAIN_NEW_VIEW	;
--DROP TABLE 	bpm_toheyue_htfkjlkemu_view;
--DROP TABLE 	bpm_lxiangyanshoukemu_view;
--DROP TABLE 	bpm_htyufukuankemu_view;SELECT * INTO bpm_QY_ContractType_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_ContractType_view') TEMP;
SELECT * INTO bpm_QY_Legal_view 
from openquery(BPM,'select 
NBFRZTID, GSMC, NSRSBH, FDDLR, GSDZ, YZBM, LXDH, BZ, NBFRBH, KAIHUHANG, KAIHUMINGCHENG, KAIHUZHUANGHAO, CJR, CJSJ,XGR, XGSJ, LIANHANCODE, AREACODEINFO, REC_PROVINCE, REC_CITY, USAGE, TYPES ,cast(RecordStatus AS varchar(10))  AS  RecordStatus
from sgbpm_prd.bpm_QY_Legal_view') a;SELECT * INTO bpm_QY_Subject_view from openquery(BPM, 'select 
YUSUANKEMUID                  ,
YUSUANKEMUMINGCHENG           ,
YUSUANKEMUBIANHAO             ,
FUJIKEMUID                    ,
KEMUJIBIE                     ,
cast(SHIFOUMOJIKEMU AS varchar(10))           AS     SHIFOUMOJIKEMU,
CHANNELTYPE                   ,
ISBAOXIAO                     ,
COSTTYPE                      ,
ISCHECKEXTRACT                ,
ISCHECKPACT                   ,
ISHOUSE                       ,
ISNEGATIVE                    ,
ISKEMUADJUST                  ,
MINLXZHAOBIAOJINE             ,
MAXFEIHETONGLXJINE            ,
MAXLXYANSHOUJINE              ,
YUSUANLEIXING                 ,
PROJECTTYPE                   ,
SUBJECTTYPE                   ,
ASSESSMENT_TYPE               ,
YUSUANKEMUSHUILV              ,
GXMC                          ,
YUSUANKEMUSHUOMING            ,
XIUGAIREN                     ,
XIUGAISHIJIAN                 ,
cast(RECORDSTATUS AS varchar(10))           AS     RECORDSTATUSfrom sgbpm_prd.bpm_QY_Subject_view') TEMP;
SELECT * INTO bpm_QY_BudgetMapKM_view from openquery(BPM,'select YUSUANKEMUID       ,
NEWKMMC            ,
NEWKMBH            ,
CHANNELTYPE        ,
COSTTYPE           ,
PROJECTTYPE        ,
SUBJECTTYPE        ,
OLDKMMC            ,
OLDKMBH            ,
CJR                ,
CJSJ               ,
XGR                ,
XGSJ               ,  
cast(RecordStatus AS varchar(10))           AS     RecordStatusfrom sgbpm_prd.bpm_QY_BudgetMapKM_view') a;
SELECT * INTO bpm_QY_Project_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_Project_view') TEMP;
SELECT * INTO bpm_QY_BudgetZT_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_BudgetZT_view') TEMP;
SELECT * INTO bpm_QY_BudgetMapZT_view from openquery(BPM, 'select 
ID, OLDZTBH, OLDZTMC, NEWZTID, NEWZTBH, NEWZTMC, CJR, CJSJ, XGR, XGSJ, TYPE, STATUS, TYPENAME
,  
cast(RecordStatus AS varchar(10))           AS     RecordStatusfrom sgbpm_prd.bpm_QY_BudgetMapZT_view') TEMP;SELECT * INTO bpm_QY_ContractBasic_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_ContractBasic_view') TEMP;
SELECT * INTO bpm_QY_ContractParty_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_ContractParty_view') TEMP;
SELECT * INTO bpm_QY_ContractPayment_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_ContractPayment_view') TEMP;
SELECT * INTO bpm_QY_ContractAppendices_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_ContractAppendices_view') TEMP;
SELECT * INTO bpm_QY_ContractCost_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_ContractCost_view') TEMP;
SELECT * INTO bpm_QY_YS_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_YS_view') TEMP;
SELECT * INTO bpm_QY_YS_PayPlan_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_YS_PayPlan_view') TEMP;
SELECT * INTO bpm_QY_YS_Subject_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_YS_Subject_view') TEMP;
SELECT * INTO bpm_QY_YS_Settlement_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_YS_Settlement_view') TEMP;
SELECT * INTO bpm_QY_YS_File_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_YS_File_view') TEMP;--SELECT * INTO bpm_fkjl_heyue_view from openquery(BPM, 'select * from sgbpm_prd.bpm_fkjl_heyue_view') TEMP;SELECT * INTO bpm_QY_LX_Basic_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_LX_Basic_view') TEMP;
SELECT * INTO bpm_QY_LX_Subject_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_LX_Subject_view') TEMP;
SELECT * INTO bpm_QY_LX_File_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_LX_File_view') TEMP;
SELECT * INTO bpm_QY_LX_Release_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_LX_Release_view') TEMP;SELECT * INTO bpm_QY_ContractMatter_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_ContractMatter_view') TEMP;
SELECT * INTO bpm_QY_Provision_gys_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_Provision_gys_view') TEMP;
SELECT * INTO bpm_QY_Provision_jtmx_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_Provision_jtmx_view') TEMP;
SELECT * INTO bpm_QY_Provision_view from openquery(BPM, 'select * from sgbpm_prd.bpm_QY_Provision_view') TEMP;SELECT * INTO bpm_QY_Department_view from VIEW_SS_bpm_QY_Department_view TEMP;
SELECT * INTO bpm_QY_Company_view from VIEW_SS_bpm_QY_Company_view TEMP;
SELECT * INTO bpm_QY_Person_view from VIEW_EAS_PERSON TEMP;--SELECT * INTO BPM_JITICHONGXIAO_NEW_VIEW  from  openquery(BPM,'select * from sgbpm_prd.BPM_JITICHONGXIAO_NEW_VIEW where xmbh
--IN(''HSHS379'',''ZJZJ457'',''XHS288'',''HSHS370'') and ZTLX=''1''') a;
--SELECT * INTO BPM_JITICHONGXIAOMAIN_NEW_VIEW  from  openquery(BPM,'select * from sgbpm_prd.BPM_JITICHONGXIAOMAIN_NEW_VIEW') a;--SELECT 
--* INTO bpm_toheyue_htfkjlkemu_view 
-- from  openquery(BPM,'select * from sgbpm_prd.bpm_toheyue_htfkjlkemu_view') a;
--SELECT * FROM QY_Project WHERE [项目名称] IN ('成都温江合生汇','北京朝阳合生汇','广州海珠合生广场南区','广州海珠合生广场北区')--SELECT * INTO bpm_lxiangyanshoukemu_view  from  openquery(BPM,'select * from sgbpm_prd.bpm_lxiangyanshoukemu_view') a;--SELECT * INTO bpm_htyufukuankemu_view  from  openquery(BPM,'select * from sgbpm_prd.bpm_htyufukuankemu_view') a;end
GO

3.执行完上述的Proc_IN_BPM存储过程,我们会发现自己的中间库中多了很多QY_Tables表中BPMTable列下的表,这就是我们同步过来的数据源表,后续所有操作都是在这些表上做处理

4.清洗过程:

  1.  编写试图VIEW_SQL_Proc_IN,得到第三方数据源中文字段的数据源表,得到中文字段主要目的是方便数据核实
    create VIEW VIEW_SQL_Proc_IN AS
    SELECT 
    'CREATE proc Proc_IN_'+QyTableName+' AS begin INSERT INTO '+QyTableName+
    ' ('+LEFT(BPMList2,LEN(BPMList2)-1)+') '+
    ' SELECT ' +LEFT(BPMList,LEN(BPMList)-1)
    + ' FROM '+BPMVIEW + ' END GO ' AS SQL2
    FROM (SELECT QyTableName,BPMTable,BPMVIEW,(SELECT SQL1+',' FROM VIEW_CheckSQLWHERE QyTableName=A.QyTableNameFOR XML PATH('')) AS BPMList,(SELECT QyTableFieldName+',' FROM VIEW_CheckSQLWHERE QyTableFieldCodeBPM IS NOT NULL AND QyTableName=A.QyTableNameFOR XML PATH('')) AS BPMList2FROM VIEW_CheckSQL A--WHERE QyTableName='QY_ContractType'GROUP BY QyTableName,BPMTable,BPMVIEW
    )TEMP
    WHERE BPMList <> ''
    GOcreate VIEW VIEW_CheckSQL ASSELECT T.Business,T.TableName,T.BPMTable,T.BPMVIEW,M.QyTableName,M.QyTableFieldName,M.QyTableFieldCodeBPM,M.QyIsNull,M.QyIsNullBPM,CASE WHEN M.QyDeaultBPMValue IS NULL THEN M.QyTableFieldCodeBPM+ +' AS ['+M.QyTableFieldName+']'ELSE 'ISNULL('+M.QyTableFieldCodeBPM+','''+M.QyDeaultBPMValue+''')'+' AS ['+M.QyTableFieldName+']'END AS SQL1FROMVIEW_Qy_Maping MLEFT JOIN VIEW_QY_Tables T ON T.TableCode=M.QyTableNameWHERE QyTableFieldName IS NOT NULL
    GO
  2. 查询VIEW_SQL_Proc_IN会得到所有表的一个存储过程的执行语句,把查询结果复制出来之后,批量执行,继而封装成存储过程
    CREATE proc [Proc_IN_QY]
    as
    BEGIN
    DELETE FROM 	QY_BudgetMapKM	;
    DELETE FROM 	 QY_BudgetMapZT	;
    DELETE FROM 	 QY_BudgetZT	;
    DELETE FROM 	 QY_ContractAppendices	;
    DELETE FROM 	 QY_ContractBasic	;
    DELETE FROM 	 QY_ContractCost	;
    DELETE FROM 	 QY_ContractParty	;
    DELETE FROM 	 QY_ContractPayment	;
    DELETE FROM 	 QY_ContractType	;
    --DELETE FROM 	 QY_Department	;
    --DELETE FROM 	 QY_Legal	;
    DELETE FROM 	 QY_LX_Basic	;
    DELETE FROM 	 QY_LX_File	;
    DELETE FROM 	 QY_LX_Release	;
    DELETE FROM 	 QY_LX_Subject	;
    DELETE FROM 	 QY_Project	;
    DELETE FROM 	 QY_ProjectLegal	;
    DELETE FROM 	 QY_Subject	;
    DELETE FROM 	 QY_YS	;
    DELETE FROM 	 QY_YS_File	;
    DELETE FROM 	 QY_YS_PayPlan	;
    DELETE FROM 	 QY_YS_Settlement	;
    DELETE FROM 	 QY_YS_Subject	;
    DELETE FROM 	 QY_YS_Pay 	;DELETE FROM 	 QY_Provision		;
    DELETE FROM 	 QY_Provision_jtmx		;
    DELETE FROM 	 QY_Provision_gys		;
    DELETE FROM 	 QY_ContractMatter		;DELETE FROM 	 QY_Company 	;
    --DELETE FROM 	 QY_Person 	;
    --DELETE FROM 	 QY_ProjectLegal 	;
    DELETE FROM 	 QY_ProjectMap 	;
    --DELETE FROM 	 QY_JITICHONGXIAOMAIN 	;exec	Proc_IN_QY_BudgetMapKM	;
    exec	 Proc_IN_QY_BudgetMapZT	;
    exec	 Proc_IN_QY_BudgetZT	;
    exec	 Proc_IN_QY_ContractAppendices	;
    exec	 Proc_IN_QY_ContractBasic	;
    exec	 Proc_IN_QY_ContractCost	;
    exec	 Proc_IN_QY_ContractParty	;
    exec	 Proc_IN_QY_ContractPayment	;
    exec	 Proc_IN_QY_ContractType	;
    --exec	 Proc_IN_QY_Legal	;
    exec	 Proc_IN_QY_LX_Basic	;
    exec	 Proc_IN_QY_LX_File	;
    exec	 Proc_IN_QY_LX_Release	;
    exec	 Proc_IN_QY_LX_Subject	;
    exec	 Proc_IN_QY_Project	;
    exec	 Proc_IN_QY_Subject	;
    exec	 Proc_IN_QY_YS	;
    exec	 Proc_IN_QY_YS_File	;
    exec	 Proc_IN_QY_YS_PayPlan	;
    exec	 Proc_IN_QY_YS_Settlement	;
    exec	 Proc_IN_QY_YS_Subject	;
    exec	 Proc_IN_QY_YS_Payexec	 Proc_IN_QY_ContractMatter	;
    exec	 Proc_IN_QY_Provision	;
    exec	 Proc_IN_QY_Provision_jtmx	;
    exec	 Proc_IN_QY_Provision_gys	;--exec	 Proc_IN_QY_Department	;
    --exec	 Proc_IN_QY_Person	;exec	 Proc_IN_QY_Company	;
    --exec	 Proc_IN_QY_ProjectLegal	;
    exec	Proc_IN_QY_ProjectMap	;
    --exec	Proc_IN_QY_JITICHONGXIAOMAIN	;exec	Proc_BPM_Clear	;
    end
    GO
  3. 执行Proc_IN_QY存储过程之后,我们会得到所有迁移数据源的中文数据源表,主要目的是为了方便数据源查看

  4. 接下来编写试图VIEW_SQL_Proc_OUT,我们把当前中间库的数据源写入到目标库

    CREATE VIEW VIEW_SQL_Proc_OUT ASSELECT 
    'if OBJECT_ID(''dbo.PROC_OUT_'+TableCode+''',''procedure'') is not null BEGIN DROP PROC dbo.PROC_OUT_' + TableCode + '  END GO'  AS SQL1
    FROM VIEW_QY_Tables
    WHERE BPMTable <> ''
    UNION
    SELECT 
    'CREATE proc Proc_OUT_'+TableCode+' AS begin INSERT INTO [HY].[HopsonCost].[dbo].'+TableCode+
    ' SELECT * FROM '+TableCode + ' END GO ' AS SQL1
    FROM VIEW_QY_Tables
    WHERE BPMTable <> ''
    GO
    
  5. 执行VIEW_SQL_Proc_OUT会得所有写出的存储过程代码,粘贴复制出来,进行执行

  6. 同样,将上述的存储过程打包进Proc_OUT_QY,便于执行

    CREATE proc [dbo].[Proc_OUT_QY]
    as
    beginDELETE FROM [HY].[HopsonCost].[dbo].QY_BudgetMapKM;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_BudgetMapZT;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_BudgetZT;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_ContractAppendices;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_ContractBasic;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_ContractCost;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_ContractParty;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_ContractPayment;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_ContractType;
    --DELETE FROM [HY].[HopsonCost].[dbo].QY_Department;
    --DELETE FROM [HY].[HopsonCost].[dbo].QY_Legal;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_LX_Basic;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_LX_File;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_LX_Release;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_LX_Subject;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_Project;
    --DELETE FROM [HY].[HopsonCost].[dbo].QY_ProjectLegal;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_Subject;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_YS;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_YS_File;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_YS_PayPlan;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_YS_Settlement;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_YS_Subject;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_YS_Pay;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_Company;
    --DELETE FROM [HY].[HopsonCost].[dbo].QY_Person;
    --DELETE FROM [HY].[HopsonCost].[dbo].QY_ProjectLegal;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_ProjectMap;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_ContractMatter;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_Provision;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_Provision_jtmx;
    DELETE FROM [HY].[HopsonCost].[dbo].QY_Provision_gys;
    --DELETE FROM [HY].[HopsonCost].[dbo].QY_JITICHONGXIAOMAIN 	;exec	Proc_OUT_QY_BudgetMapKM	;
    exec	 Proc_OUT_QY_BudgetMapZT	;
    exec	 Proc_OUT_QY_BudgetZT	;
    exec	 Proc_OUT_QY_ContractAppendices	;
    exec	 Proc_OUT_QY_ContractBasic	;
    exec	 Proc_OUT_QY_ContractCost	;
    exec	 Proc_OUT_QY_ContractParty	;
    exec	 Proc_OUT_QY_ContractPayment	;
    exec	 Proc_OUT_QY_ContractType	;
    --exec	 Proc_OUT_QY_Legal	;
    exec	 Proc_OUT_QY_Project	;
    exec	 Proc_OUT_QY_Subject	;
    exec	 Proc_OUT_QY_YS	;
    exec	 Proc_OUT_QY_YS_File	;
    exec	 Proc_OUT_QY_YS_PayPlan	;
    exec	 Proc_OUT_QY_YS_Settlement	;
    exec	 Proc_OUT_QY_YS_Subject	;
    exec	 Proc_OUT_QY_YS_Pay;
    exec	 Proc_OUT_QY_LX_Basic	;
    exec	 Proc_OUT_QY_LX_Subject	;
    exec	 Proc_OUT_QY_LX_File	;
    exec	 Proc_OUT_QY_LX_Release	;
    --exec	 Proc_OUT_QY_Department	;
    --exec	 Proc_OUT_QY_ProjectLegal	;
    exec	Proc_OUT_QY_Company	;
    --exec	Proc_OUT_QY_Person	;
    exec	Proc_OUT_QY_ProjectMap	;
    exec	 Proc_OUT_QY_ContractMatter	;
    exec	Proc_OUT_QY_Provision	;
    exec	Proc_OUT_QY_Provision_gys	;
    exec	Proc_OUT_QY_Provision_jtmx	;
    --exec	Proc_OUT_QY_JITICHONGXIAOMAIN	;--DROP TABLE [HY].[HopsonCost].[dbo].bpm_fkjl_heyue_view;
    --DROP TABLE [HY].[HopsonCost].[dbo].bpm_toheyue_htfkjlkemu_view;--SELECT * INTO [HY].[HopsonCost].[dbo].bpm_fkjl_heyue_view FROM bpm_fkjl_heyue_view;
    --SELECT * INTO [HY].[HopsonCost].[dbo].bpm_toheyue_htfkjlkemu_view FROM bpm_toheyue_htfkjlkemu_view;--DROP TABLE [HY].[HopsonCost].[dbo].bpm_htyufukuankemu_view;
    --DROP TABLE [HY].[HopsonCost].[dbo].bpm_lxiangyanshoukemu_view;--SELECT * INTO [HY].[HopsonCost].[dbo].bpm_htyufukuankemu_view FROM bpm_htyufukuankemu_view;
    --SELECT * INTO [HY].[HopsonCost].[dbo].bpm_lxiangyanshoukemu_view FROM bpm_lxiangyanshoukemu_view;end
    GO
  7. 执行完上述存储过程之后,我们会发现,在我们的目标库中生成了我们的中文字段的数据源表

5.数据写入

        1.根据得到的数据源表,可以进行code代码,结合Qy_FieldDic、Qy_ErrorMsg进行相关字段字典的转换以及日志记录

        2.某个业务的代码介绍

/// <summary>
/// 付款申请数据迁移
/// 1.1 主表记录
/// </summary>
/// <returns></returns>
public virtual HttpResponseMessage UpPaymentRequest()
{try{int totalCount = 0, successCount = 0, errorCout = 0;string fromTableName = "QY_PaymentRequest";string toTableName = "FM_PaymentRequest";string qyBUSSID = "PaymentRequestBussID";string qyCreateUserID = "CreateUserID";string qyModifyUserID = "ModifyUserID";string qyProjectID = "ProjectID";string qyContractID = "ContractID";string qyProAppID = "ProAppID";string qyImprestID = "ImprestID";using (var context = new MasterDbContext()){List<Qy_Maping> mapings = context.Qy_Maping.Where(ss => ss.QyTableName == fromTableName).ToList();List<Qy_FieldDic> fieldDics = context.Qy_FieldDic.Where(x=>x.BPMTABLE == fromTableName).ToList();var BUSSID = mapings.FirstOrDefault(ss => ss.QyTableFieldCode == qyBUSSID);if (BUSSID == null){return WebApiHelper.GetErrorHttpResponseMessage(new { Messsage = "不存在业务ID" });}DataTable dataTable = context.ExecuteDataTable("select * from " + fromTableName);totalCount = dataTable.Rows.Count;LogTxtInfo("需要迁移" + totalCount + "条");var CreateUserID = mapings.FirstOrDefault(ss => ss.QyTableFieldCode == qyCreateUserID);var ModifyUserID = mapings.FirstOrDefault(ss => ss.QyTableFieldCode == qyModifyUserID);var ProjectID = mapings.FirstOrDefault(ss => ss.QyTableFieldCode == qyProjectID);var ProAppID = mapings.FirstOrDefault(ss => ss.QyTableFieldCode == qyProAppID);var ContractID = mapings.FirstOrDefault(ss => ss.QyTableFieldCode == qyContractID);var ImprestID = mapings.FirstOrDefault(ss => ss.QyTableFieldCode == qyImprestID);for (int i = 0; i < dataTable.Rows.Count; i++){DataRow row = dataTable.Rows[i];object obj = row[BUSSID.QyTableFieldName];if (obj == null){//记录日志errorCout++;WriteLog(context, fromTableName, toTableName, "业务ID为空");continue;}object objCreateUserID = row[CreateUserID.QyTableFieldName];object objModifyUserID = row[ModifyUserID.QyTableFieldName];object objProjectID = row[ProjectID.QyTableFieldName];object objProAppID = row[ProAppID.QyTableFieldName];string objContractID = row[ContractID.QyTableFieldName].ToStr();string objImprestID = row[ImprestID.QyTableFieldName].ToStr();int ProBUSSID = 0;if (objProjectID != null){ProBUSSID = context.Database.SqlQuery<int>("SELECT ProjectID FROM dbo.CMN_Project WHERE ProBUSSID = '" + objProjectID.ToString() + "'").FirstOrDefault();ProjectID.QyDefaultValue = ProBUSSID.ToStr();}int Plixiangid = 0;if(ProAppID != null){Plixiangid = context.Database.SqlQuery<int>("SELECT ProAppID FROM CMN_SyncProjectApproval WHERE ProAppBUSSID =  '" + objProAppID + "'").FirstOrDefault();ProAppID.QyDefaultValue = Plixiangid.ToString();}int CUserID = 0;if (objCreateUserID != null){CUserID = context.Database.SqlQuery<int>("SELECT USERID FROM dbo.CF_USER WHERE USERNO = '" + objCreateUserID + "'").FirstOrDefault();CreateUserID.QyDefaultValue = CUserID.ToString();}int MUserID = 0;if (objCreateUserID != null){MUserID = context.Database.SqlQuery<int>("SELECT USERID FROM dbo.CF_USER WHERE USERNO = '" + objModifyUserID + "'").FirstOrDefault();ModifyUserID.QyDefaultValue = MUserID.ToString();}if (objContractID != "") {var tempContract = context.CON_Contract.FirstOrDefault(x => x.ContractIDBUSSID == objContractID);if (tempContract != null){ContractID.QyDefaultValue = tempContract.ContractID.ToStr();}else {LogTxtInfo("迁移失败: 未找到合同信息:objContractID=" + objContractID);//记录日志errorCout++;WriteLog(context, fromTableName, toTableName, "迁移失败: 未找到合同信息:objContractID=" + objContractID);continue;}}if (objImprestID != "") {var tempImprest = context.FM_Imprest.FirstOrDefault(x => x.BPMmainId == objImprestID);if (tempImprest != null){ImprestID.QyDefaultValue = tempImprest.ImprestID.ToStr();}else{LogTxtInfo("迁移失败: 未找到备用金信息:objImprestID=" + objImprestID);//记录日志errorCout++;WriteLog(context, fromTableName, toTableName, "迁移失败: 未找到备用金信息:objImprestID=" + objImprestID);continue;}}string updateWhere = string.Empty;if (obj.ToString() == "NULL"){updateWhere = " WHERE 1=2";}else{updateWhere = " WHERE " + qyBUSSID + "='" + obj.ToString() + "'";}string sqlCmdInsert = string.Empty;string sqlCmdUpdate = string.Empty;try{using (var dbContextTransaction = context.Database.BeginTransaction()){sqlCmdInsert = CreateInsertSqlCmd(row, toTableName, mapings, fieldDics);sqlCmdUpdate = CreateUpdateSqlCmd(row, toTableName, mapings, fieldDics) + updateWhere;List<SqlParameter> paramArray = new List<SqlParameter>();paramArray.Add(new SqlParameter("@bussid", obj.ToString()));paramArray.Add(new SqlParameter("@insertCmd", sqlCmdInsert));paramArray.Add(new SqlParameter("@updateCmd", sqlCmdUpdate));paramArray.Add(new SqlParameter("@tableName", toTableName));context.Database.ExecuteSqlCommand("[dbo].[Qy_InsertOrUpdateAndInsertPrimarykeyRelation] @bussid , @insertCmd , @updateCmd , @tableName  ", paramArray.ToArray());dbContextTransaction.Commit();successCount++;}}catch (Exception ex){//记录日志errorCout++;WriteLog(context, fromTableName, toTableName, ex.ToString(), sqlCmdInsert, sqlCmdUpdate);continue;}}}LogTxtInfo("迁移完毕,总计:" + totalCount + "条,成功:" + successCount + "条,失败:" + errorCout + "条");return WebApiHelper.GetOkHttpResponseMessage(new { Messsage = "迁移完毕,总计:" + totalCount + "条,成功:" + successCount + "条,失败:" + errorCout + "条" });}catch (Exception ex){LogTxtInfo("迁移异常:" + ex.Message.ToString());return WebApiHelper.GetErrorHttpResponseMessage(new { Messsage = ex.Message.ToString() });}
}
/// <summary>
/// 创建插入数据SQL
/// </summary>
/// <param name="dataRow"></param>
/// <param name="tableName"></param>
/// <param name="mapings"></param>
/// <param name="fieldDics"></param>
/// <returns></returns>
private string CreateInsertSqlCmd(DataRow dataRow, string tableName, List<Qy_Maping> mapings, List<Qy_FieldDic> fieldDics)
{mapings = mapings.Where(ss => ss.QyTableFieldCode != null).ToList();StringBuilder sqlAppend = new StringBuilder();sqlAppend.Append("INSERT INTO " + tableName + "");sqlAppend.Append("( ");List<string> fields = new List<string>();foreach (var item in mapings){fields.Add(item.QyTableFieldCode);}sqlAppend.Append(string.Join(",", fields));sqlAppend.Append(")");sqlAppend.Append("VALUES ");sqlAppend.Append("( ");List<string> values = new List<string>();for (int k = 0; k < mapings.Count; k++){Qy_Maping maping = mapings[k];try{string QyTableFieldName = maping.QyTableFieldName;if (string.IsNullOrEmpty(QyTableFieldName)){if (string.IsNullOrEmpty(maping.QyDefaultValue)){values.Add("NULL");}else{//values.Add("'" + mapings[k].QyDefaultValue + "'");values.Add(GetFieldTypeForValue(maping.QyTableFieldType, maping.QyDefaultValue));}}else{//如果设置默认值,则强制覆盖if (!string.IsNullOrEmpty(maping.QyDefaultValue)){//values.Add("'" + mapings[k].QyDefaultValue + "'");values.Add(GetFieldTypeForValue(maping.QyTableFieldType, maping.QyDefaultValue));}else{object obj = dataRow[QyTableFieldName];if (obj != null && !string.IsNullOrEmpty(obj.ToString())){string value = GetValue(obj, maping.QyPOPTYPE, maping.QyPOPTYPEValueSouce, fieldDics);if (value == "NULL")values.Add(value);else//values.Add(value);values.Add(GetFieldTypeForValue(maping.QyTableFieldType, value));}else{if (!string.IsNullOrEmpty(maping.QyRelaceNullValue)){values.Add(GetFieldTypeForValue(maping.QyTableFieldType, maping.QyRelaceNullValue));}elsevalues.Add(" NULL ");}}}}catch (Exception ex){throw new Exception("错误字段:" + maping.QyTableFieldName + ",错误消息:" + ex.Message);}}sqlAppend.Append(string.Join(",", values));sqlAppend.Append(")");return sqlAppend.ToString();
}/// <summary>
/// 创建更新数据SQL
/// </summary>
/// <param name="dataRow"></param>
/// <param name="tableName"></param>
/// <param name="mapings"></param>
/// <param name="fieldDics"></param>
/// <returns></returns>
private string CreateUpdateSqlCmd(DataRow dataRow, string tableName, List<Qy_Maping> mapings, List<Qy_FieldDic> fieldDics)
{mapings = mapings.Where(ss => ss.QyTableFieldCode != null).ToList();List<string> sqlCmdUpdateTabel = new List<string>();StringBuilder sqlAppend = new StringBuilder();sqlAppend.Append("UPDATE " + tableName + " SET ");List<string> values = new List<string>();for (int k = 0; k < mapings.Count; k++){Qy_Maping maping = mapings[k];try{string QyTableFieldName = maping.QyTableFieldName;if (string.IsNullOrEmpty(QyTableFieldName)){if (string.IsNullOrEmpty(maping.QyDefaultValue)){values.Add(maping.QyTableFieldCode + "= NULL ");}else{values.Add(mapings[k].QyTableFieldCode + " = " + GetFieldTypeForValue(maping.QyTableFieldType, maping.QyDefaultValue));}}else{//如果设置默认值,则强制覆盖if (!string.IsNullOrEmpty(maping.QyDefaultValue)){values.Add(maping.QyTableFieldCode + "= " + GetFieldTypeForValue(maping.QyTableFieldType, maping.QyDefaultValue));}else{object obj = dataRow[QyTableFieldName];if (obj != null && !string.IsNullOrEmpty(obj.ToString())){string value = GetValue(obj, maping.QyPOPTYPE, maping.QyPOPTYPEValueSouce, fieldDics);if (value == "NULL")values.Add(maping.QyTableFieldCode + "= NULL ");elsevalues.Add(maping.QyTableFieldCode + " = " + GetFieldTypeForValue(maping.QyTableFieldType, value));}else{if (!string.IsNullOrEmpty(maping.QyRelaceNullValue)){values.Add(maping.QyTableFieldCode + " = " + GetFieldTypeForValue(maping.QyTableFieldType, maping.QyRelaceNullValue));}elsevalues.Add(maping.QyTableFieldCode + "= NULL ");}}}}catch (Exception ex){throw new Exception("错误字段:" + maping.QyTableFieldName + ",错误消息:" + ex.Message);}}sqlAppend.Append(string.Join(",", values));return sqlAppend.ToString();
}/// <summary>
/// 根据字段类型创建SQL语句的Values
/// </summary>
/// <param name="QyTableFieldType"></param>
/// <param name="Value"></param>
/// <returns></returns>
private string GetFieldTypeForValue(string QyTableFieldType, string Value)
{try{if (string.IsNullOrEmpty(QyTableFieldType))return "'" + Value + "'";string fieldValue = string.Empty;switch (QyTableFieldType){case "char": fieldValue = "'" + Value + "'"; break;case "date": fieldValue = "'" + Value + "'"; break;case "datetime": fieldValue = "'" + Convert.ToDateTime(Value).ToString("yyyy-MM-dd HH:mm:ss") + "'"; break;case "int": fieldValue = Convert.ToInt32(Value).ToString(); break;case "decimal": fieldValue = Convert.ToDecimal(Value).ToString(); break;case "nvarchar": fieldValue = "'" + Value.Replace("'", "’") + "'"; break;case "VARCHAR2": fieldValue = "'" + Value.Replace("'", "’") + "'"; break;case "NUMBER": fieldValue = Convert.ToInt32(Value).ToString(); break;case "NUMBER(20,4)": fieldValue = Convert.ToDecimal(Value).ToString(); break;case "TIMESTAMP": fieldValue = "to_timestamp('" + Convert.ToDateTime(Value).ToString() + "','YYYY-MM-DDHH24:MI:SS')"; break;case "DATE": fieldValue = "to_date('" + Convert.ToDateTime(Value).ToString() + "','YYYY-MM-DDHH24:MI:SS')"; break;default: fieldValue = "'" + Value + "'"; break;}return fieldValue;}catch (Exception ex){throw new Exception(ex.Message);}
}/// <summary>
/// 记录错误日志
/// </summary>
/// <param name="context"></param>
/// <param name="fromTable"></param>
/// <param name="toTable"></param>
/// <param name="errorMsg"></param>
/// <param name="sqlCmdInsert"></param>
/// <param name="sqlCmdUpdate"></param>
private void WriteLog(MasterDbContext context, string fromTable, string toTable, string errorMsg, string sqlCmdInsert = "", string sqlCmdUpdate = "")
{string sqlCmdLog = "INSERT INTO[dbo].[Qy_ErrorMsg]([FromTableName],[ToTableName],[ErrorMsg],[ErrorInsertSqlCmd],[ErrorUpdateSqlCmd]) VALUES(@FromTableName,@ToTableName,@ErrorMsg,@ErrorInsertSqlCmd,@ErrorUpdateSqlCmd)";List<SqlParameter> paramArray = new List<SqlParameter>();paramArray.Add(new SqlParameter("@FromTableName", fromTable));paramArray.Add(new SqlParameter("@ToTableName", toTable));paramArray.Add(new SqlParameter("@ErrorMsg", errorMsg));paramArray.Add(new SqlParameter("@ErrorInsertSqlCmd", sqlCmdInsert));paramArray.Add(new SqlParameter("@ErrorUpdateSqlCmd", sqlCmdUpdate));context.Database.ExecuteSqlCommand(sqlCmdLog, paramArray.ToArray());
}

总结

        至此,整体的迁移完成。迁移过程中,其实没有太多难点,只是更多的需要耐心细心。同样,上述的迁移思路也可以进行简化。只不过,个人认为,这样做更安全、更便于后期数据的核实等工作。当然,还有其他更多的一些方案,欢迎一起交流~~~

更多推荐

记一次数据迁移的全过程

本文发布于:2024-02-06 08:28:22,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1747619.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:全过程   数据

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!