sqlserver数据库转存到oracle

sqlserver数据库转存到oracle,第1张

概述需求:实现远程sqlserver数据库转存到oracle中,同时实现每天的凌晨两点转一次,一次转三个月内的数据,oracle中存在时就更新,不存在时就插入,因为数据有点多,一天数据就有五百条左右,插入时性能得调整。 难点: 1、两个数据库的连接(比较简单,但是细节很重要) 2、性能好点的插入更新sql 3、怎么实现每天定时更新 4、一次性同步数据较多,会使得系统直接卡死(我那破本本,重启了四五次) 需求:实现远程sqlserver数据库转存到oracle中,同时实现每天的凌晨两点转一次,一次转三个月内的数据,oracle中存在时就更新,不存在时就插入,因为数据有点多,一天数据就有五百条左右,插入时性能得调整。

难点:
1、两个数据库的连接(比较简单,但是细节很重要)
2、性能好点的插入更新sql
3、怎么实现每天定时更新
4、一次性同步数据较多,会使得系统直接卡死(我那破本本,重启了四五次)

解决方案:
1、对于oracle的连接其实很简单,因为oracle是本地的所以连接很easy,连接字符串搞定就行
</pre><pre name="code" >//oracle连接字符串string oracleConnectStr = "Data source=数据库名;user ID=登录名;password=密码";//例如:string oracleConnectStr = "Data source=orcl;user ID=lIEms3;password=lIEms3";
2、对于sqlserver的连接有点坑爹,看是很简单,但是 *** 作的时候各种坑爹,因为sqlserver版本太多,我自己测试用的2012,实施用的是2000,产生了代沟,怎么都连不上。
//sqlserver连接字符串string sqlserverConnectStr = "Data Source=远程IP;Initial Catalog=数据库;User ID=登录名;Password=密码";//string sqlserverConnectStr = "Data Source=168.168.10.77;Initial Catalog=jamIE;User ID=sa;Password=jamIE";
连接的时候会出现下面的异常:

异常 System.Data.sqlClIEnt.sqlException (0x80131904): 在与 sql Server 建立连接时出现与网络相关的或特定于实例的错误。未找到或无法访问服务器。请验证实例名称是否正确并且 sql Server 已配置为允许远程连接。 (provIDer: named Pipes ProvIDer,error: 40 - 无法打开到 sql Server 的连接)

之后就会使劲的去百度异常问题,但是有的时候可能都不是这些问题,就拿sqlserver 2000的来说吧,2000有个神马sqlserver注册组,注册组下有数据库,用查询分析器连接的时候127.0.0.1都连不进去,需要在后面加注册组中的完整地址像下面这样

string sqlserverConnectStr = "Data Source=127.0.0.1\ERP;Initial Catalog=jamIE;User ID=sa;Password=jamIE";

 3、性能好点的插入语句这里介绍merge into 根据条件插入或更新,语句简单性能好,至于详细各位自己勾搭度娘去,merge into 能很好的同步数据库中两张表的数据,对于不同数据库的数据同步,我开始也是纠结了好久,之后提出两种方案,都是可行的,一种是建一张临时表将sqlserver中查到的数据插入进去之后再更新,这种是可行的,一个同事就是用的这种,一种是直接用sql将查到的数据拼成一张表(这里不知道如何表达,其实我也是第一次见到这么神奇的东东)

sqlStr=@"select 123 as dualp_ID,'jamIE' as dual_name,18 as dual_age from dualunion allselect 312 as dualp_ID,'tom' as dual_name,19 as dual_age from dualunion allselect 321 as dualp_ID,'jane' as dual_name,20 as dual_age from dual"
这样就形成了一张表,一张比临时表还临时的表。不要问我中间的原因是什么,我也不知道,大神叫我这么做的。之后再上merge into语句
sqlo = string.Format(@"merge into cement_in indata using ({0}) temp on(indata.FInterID=temp.FInterID and indata.FEntryID=temp.FEntryID)when matched thenupdate set indata.FDate = temp.FDate,indata.FQty = temp.FQty,indata.fprice = temp.fprice,indata.famount = temp.famount,indata.funitID = temp.funitID,indata.FTranType =temp.FTranType,indata.FSupplyID = temp.FSupplyID,indata.FItemID = temp.FItemID,indata.fnumber = temp.fnumber,indata.itemname =temp.itemname,indata.fmodel =temp.fmodel,indata.supplyname =temp.supplyname,indata.unitname =temp.unitname,indata.typename =temp.typenamewhen not matched then insert (FInterID,FEntryID,FDate,FQty,fprice,famount,funitID,FTranType,FSupplyID,FItemID,fnumber,itemname,fmodel,supplyname,unitname,typename)values(temp.FInterID,temp.FEntryID,temp.FDate,temp.FQty,temp.fprice,temp.famount,temp.funitID,temp.FTranType,temp.FSupplyID,temp.FItemID,temp.fnumber,temp.itemname,temp.fmodel,temp.supplyname,temp.unitname,temp.typename)",sqlStr);//	组成的那个超临时表的@R_419_5967@	
这样一个OK的merge into sql 就出来了,sql好长呀,其实这是很短的,因为数据只有三条,想想数据达到几百条几千条之后又有多少页了,反正我将整个sql复制到plsql之中就等了好久plsql才反应过来。

4、接着就是数据太多性能的问题了,一般同步300条数据的时候一秒就ok了,但是到了500以上就蛋疼了,特别是5000条的时候整个本本都game over,等了十几分钟最后只能关机重启。对于这种问题,解决方案是将数据分为300条一组数据存入到一个List,之后每300条同步一次,效果一下就很明显了,5000条数据70秒就搞定了。so easy ,大神再也不会看到我关机重启了。

5、至于每天定时运行,这个其实也很简单,我用的是一个叫jobAnt的工具,大神提供的,各种碉堡了,定时运行无压力。下面就上代码吧!

using System;using System.Collections.Generic;using System.linq;using System.Text;using System.Data.sqlClIEnt;using System.Data.OracleClIEnt;namespace Datatransform{	public class transform	{		//总共处理数据条数		private int sumData=0;  		//开始时间		private DateTime startTime;		//结束时间		private DateTime endTime;		//是否是 *** 作入库表		private bool isIn;		//一次更新条数		private int updateNumber = 500;		//oracle连接字符串		private string oracleConnectStr = "Data source=orcl;user ID=lIEms3;password=lIEms3";		//sqlserver连接字符串		private string sqlserverConnectStr = "Data Source=168.168.10.77;Initial Catalog=jamIE;User ID=sa;Password=jamIE";		//入库表的sql		string sqlReadIn = string.Format(@"select * from cement_in where FDate between DateAdd(Month,-3,getdate()-1) and DateAdd(Month,-2,getdate()) ;");		//出库表的sql		string sqlReadOut = string.Format(@"select * from cement_out where FDate between DateAdd(Month,getdate()) ;");		List<String> sqlList = null;		public voID ReadFromsqlServer(bool isin)		{			this.isIn = isin;			sqlConnection sqlCon = null;			sqlCommand cmdsql = null;			sqlDataReader dataReader = null;			OracleConnection conn = null;			OracleCommand cmdORA = null;			try			{				sqlCon = new sqlConnection(sqlserverConnectStr);				sqlCon.open();				conn = new OracleConnection(oracleConnectStr);				conn.open();				string sqls = null;				if (isIn)				{					sqls = sqlReadIn;				}				else				{					sqls = sqlReadOut;				}				cmdsql = new sqlCommand(sqls,sqlCon);				dataReader = cmdsql.ExecuteReader();				string sqlUion = "";				int num = 1;				sqlList = new List<string>();				while (dataReader.Read())				{					string strTemp;					if (isIn)					{						strTemp = string.Format(@"select 													{0} as FInterID,{1} as FEntryID,to_date('{2}','yyyy-mm-dd hh24:mi:ss') as FDate,{3} as FQty,{4} as fprice,{5} as famount,{6} as funitID,{7} as FTranType,'{8}' as FSupplyID,{9} as FItemID,{10} as fnumber,'{11}' as itemname,'{12}' as fmodel,'{13}' as supplyname,'{14}' as unitname,'{15}' as typename from  dual",Convert.ToInt32(dataReader["FInterID"]),Convert.ToInt32(dataReader["FEntryID"]),Convert.ToString(dataReader["FDate"]),Convert.Todouble(dataReader["FQty"]),Convert.Todouble(dataReader["fprice"]),Convert.Todouble(dataReader["famount"]),Convert.ToInt32(dataReader["funitID"]),Convert.ToInt32(dataReader["FTranType"]),Convert.ToString(dataReader["FSupplyID"]),Convert.ToInt32(dataReader["FItemID"]),Convert.Todouble(dataReader["fnumber"]),Convert.ToString(dataReader["itemname"]),Convert.ToString(dataReader["fmodel"]),Convert.ToString(dataReader["supplyname"]),Convert.ToString(dataReader["unitname"]),Convert.ToString(dataReader["typename"])							);					}					else					{						strTemp = string.Format(@"select 													{0} as FInterID,{6} as saleprice,{7} as saleamount,'{8}' as funitID,{9} as FTranType,{10} as FSupplyID,'{11}' as FItemID,{12} as fnumber,'{13}' as itemname,'{14}' as supplyname,'{15}' as unitname,'{16}' as typename from  dual",Convert.ToInt32(dataReader["saleprice"]),Convert.ToInt32(dataReader["saleamount"]),Convert.ToInt32(dataReader["FSupplyID"]),Convert.ToString(dataReader["typename"]));					}					sqlUion += strTemp;					if (num % updateNumber == 0)					{						sqlList.Add(sqlUion);						sqlUion = "";					}					else					{						sqlUion += " union all ";					}					num++;				}				if (!"".Equals(sqlUion))				{					string sqlu = sqlUion.Substring(0,sqlUion.Length - 10);					sqlList.Add(sqlu);				}				string sqlo = null;				foreach (var item in sqlList)				{					if (isIn)					{						sqlo = string.Format(@"merge into cement_in indata using ({0}) temp on(indata.FInterID=temp.FInterID and indata.FEntryID=temp.FEntryID)							when matched then							update set indata.FDate = temp.FDate,indata.typename =temp.typename							when not matched then 							insert 							(FInterID,typename)							values							(temp.FInterID,item);					}					else					{						sqlo = string.Format(@"merge into cement_out outdata using ({0}) temp on(outdata.FInterID=temp.FInterID and outdata.FEntryID=temp.FEntryID)							when matched then							update set outdata.FDate = temp.FDate,outdata.FQty = temp.FQty,outdata.fprice = temp.fprice,outdata.famount = temp.famount,outdata.funitID = temp.funitID,outdata.FTranType =temp.FTranType,outdata.FSupplyID = temp.FSupplyID,outdata.FItemID = temp.FItemID,outdata.fnumber = temp.fnumber,outdata.itemname =temp.itemname,outdata.saleprice =temp.saleprice,outdata.saleamount =temp.saleamount,outdata.supplyname =temp.supplyname,outdata.unitname =temp.unitname,outdata.typename =temp.typename							when not matched then 							insert 							(FInterID,saleprice,saleamount,temp.saleprice,temp.saleamount,item);					}					cmdORA = new OracleCommand(sqlo,conn);					var val = cmdORA.ExecuteNonquery();					if (val >= 1)					{						Console.Writeline("insert or update count: " + val);					}				}			}			catch (Exception ex)			{				throw ex;			}			finally			{				cmdORA.dispose();				conn.Close();				dataReader.Close();				cmdsql.dispose();				sqlCon.Close();			}		}	}}
<a target=_blank href="http://download.csdn.net/detail/jiangyou4/8535829">点击打开链接</a>
总结

以上是内存溢出为你收集整理的sqlserver数据库转存到oracle全部内容,希望文章能够帮你解决sqlserver数据库转存到oracle所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/1161633.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存