SQL SERVER 2008向ORACLE 11G迁移示例
来源于:http://www.cnblogs.com/hiizsk/
由SQL SERVER 2008向ORACLE 11G迁移过程记录之一-表
使用Oracle Sql Developer将SQL SERVER 2008数据库移植到Oracle 11g(一)
使用Oracle Sql Developer将SQL SERVER 2008数据库移植到Oracle 11g(二)
使用Oracle Sql Developer将SQL SERVER 2008数据库移植到Oracle 11g(三)
使用Oracle Sql Developer将SQL SERVER 2008数据库移植到Oracle 11g(四)
使用Oracle Sql Developer将SQL SERVER 2008数据库移植到Oracle 11g(五)
最近在将项目由SQL SERVER 2008向ORACLE 11G迁移,以下简述迁移数据表过程。
- 产生数据库的脚本。在脚本生成向导中选择脚本选项中,设置ANSI填充FALSE、编写USE DATABASE脚本FALSE、编写扩展属性脚本FALSE、架构限定对象名称FALSE,为服务器版本编写脚本选择SQL SERVER 2008
- 生成到新文件或到新窗口后保存到文件,然后使用支持正则表达式的文本编辑器打开(建议使用EmEditor,否则可能下面某些正则表达式会稍有不同),使用查找替换功能依次如下操作(以下如未说明则都为使用正则表达式查找):
- 由于ORACLE的名称限定符是引号而非方括号,因此要将[和]替换成空字符串以去除。假如有使用关键字作为名称的,需要再单独处理了
查找:\[|\]
替换为:空字符串 - 去除SET ANSI_NULLS ON和SET QUOTED_IDENTIFIER ON,因为ORACLE中不存在这些属性或不是这个名称,使用正则可以很方便的完成这个工作:
查找:SET ANSI_NULLS ON\nGO\nSET QUOTED_IDENTIFIER ON\nGO\n
替换为:空字符串。 - 替换所有的GO为;同样使用正则表达式来做:
查找:\nGO\n
替换为:;\n - 注释掉IDENTITY(1,1),因为ORACLE中不支持这个关键字,相应的,为了实现自增数字的功能,需要建立一个SEQUENCE,然后在表上建立一个INSERT触发器,触发时往对应字段赋值为代替。后面我会写一个PYTHON脚本,根据这些注释生成所有的SEQUENCE和触发器脚本。
查找:(IDENTITY\(\d+,\d+\))
替换为:/*\1*/ - 去除所有的“ ON PRIMARY”,“ TEXTIMAGE_ON PRIMARY”
查找:TEXTIMAGE_ON PRIMARY|ON PRIMARY
替换为:空字符串 - 去除所有的“ CLUSTERED ”、“ NONCLUSTERED ”、“WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)”
查找:((NON)*CLUSTERED)|(WITH \(PAD[^\)]+\))
替换为:空字符串 - 主键语句中,去除ASC和DESC,注意别误伤视图语句中的相应字符串。
查找:( ASC| DESC) 注意字符前的空格,以免误伤标识符中的对应字符
替换为:空字符串 - 替换字段类型。因为SQL SERVER中的类型和ORACLE中大部分都不一样,因此基本上都需要替换掉。具体替换时建议按如下步骤(注意如果在标识符中没有关键字,那么在替换时勾选全字匹配即可,如果可能存在使用关键字当标识符的时候,那么,查找时使用正则表达式,在查找字符串前加上[ ]^1,表示查找字符串前存在并只存在1个空格,如原类型后必然有括号的,例如char/varchar之类,那么在查找字符串后加上\(,必然没有括号的加上[ ]^1,然后在替换字符串中根据前后是否有空格或括号,要依样加上,如int替换成number(10,0),使用正则时,查找字符串内填[ ]^1int[ ]^1,替换字符串内填 NUMBER(10,0) ,注意前后的空格,再如varchar替换成varchar2时,查找字符串填[ ]^1varhcar\(,替换字符串写 varchar2(,注意前面的空格和后面的括号。):
- varchar替换成varchar2
- nvarchar也是替换成varchar2,但是长度要乘2,所以这个要单独每种长度都独立替换
- 同样要乘2的还包括所有n开头的类型
- int替换成NUMBER(10,0)
- NUMERIC和DECIMAL替换成NUMBER
- smalldatetime和datetime替换成DATE
- text替换成CLOB
- image替换成BLOB
- 其它类型对应表如下:
SQL SERVER ORACLE 数字类型 DECIMAL[(P[,S])] NUMBER[(P[,S])] NUMERIC[(P[,S])] NUMBER[(P[,S])] FLOAT[(N)] NUMBER[(N)] FLOAT[(N)] NUMBER[(N)] INT NUMBER SMALLINT NUMBER TINYINT NUMBER MONEY NUMBER[19,4] SMALLMONEY NUMBER[19,4] 字符类型 CHAR[(N)] CHAR[(N)] VARCHAR[(N)] VARCHAR2[(N)] NCHAR[(N)] CHAR[(N*2)] NVARCHAR[(N)] VARCHAR2[(N*2)] 日期时间类型 DATETIME DATE SMALLDATETIME DATE 其它 TEXT CLOB IMAGE BLOB BIT NUMBER(1) UNIQUEIDENTIFIER LONG RAW
- 替换默认值规则:
- 替换默认日期:
查找(普通非正则):(getdate())
替换为:SYSDATE - 数字默认值语法替换,把数字外的括号去除:
查找:( DEFAULT )\((\d+)\)
替换为:\1\2 - 替换默认值语法:
查找:ALTER TABLE (\w+) ADD\s+CONSTRAINT.+DEFAULT (.+) FOR (\w+);
替换为:alter table \1 modify \3 default \2;
- 替换默认日期:
- 去除外键语句中一些不支持的选项(在我的数据库中碰到的。应该不完整),以及,SQL SERVER生成的约束有时会先使用WITH NOCHECK创建约束后紧跟着将之启用,虽然可以用ORACLE对应的DISALBE和ENABLE选项替代,但感觉没有什么用,于是干脆把WITH NOCHECK去掉,同时却掉紧跟着的启用约束语句。具体如下:
查找:ON UPDATE CASCADE\n|\nNOT FOR REPLICATION|ALTER TABLE.+CHECK CONSTRAINT.+\n|WITH NOCHECK|WITH CHECK
替换为:空字符串
- 由于ORACLE的名称限定符是引号而非方括号,因此要将[和]替换成空字符串以去除。假如有使用关键字作为名称的,需要再单独处理了
- 转换的过程中,应注意以下问题:
- 标识符长度不能超过30(包括表、约束、视图等等所有的标识标)
- varchar2的长度不能超过4000
- 好的,保存修改后的SQL脚本文件,现在可以给ORACLE执行了吗?等等,还有。。我们要生成IDENTITY的替代脚本!下面是PYTHON脚本代码,把它保存为文本文件,例如c:\convert.py中,然后,在CMD中执行
c:\>%path_to_python.exe% c:\convert.py [sql原文件路径] [生成的触发器和seqence的sql文件保存路径]
不过,这个脚本只支持一个表中存在一个IDENTITY字段的情况。:(
#coding=utf-8
import sys
import re
#sys.setdefaultencoding('utf8')
orgfile=sys.argv[1]
newfile=sys.argv[2]
f=open(orgfile,'r')
fidentity=open(newfile,"w")line=f.read()
p=re.compile('CREATE TABLE ([^\(\n]+)[^;]+?(\S+) NUMBER\(10,0\)/\* IDENTITY\((\d+),(\d+)\)\*/',re.I|re.S|re.M)
mat=p.findall(line)
for item in mat:
seqname="SEQ_"+item[0]
triggername="TRI_"+item[0]+"_"+item[1]if len(seqname)>30:
seqname=seqname[0:29]
if len(triggername)>30:
triggername=triggername[0:29]
createseq="create sequence "+seqname+" increment by "+item[3]+" start with "+item[2]+";\n"
createseq=createseq+"CREATE OR REPLACE TRIGGER " + triggername +"\n\
BEFORE INSERT ON "+item[0]+"\n\
FOR EACH ROW\n\
WHEN (new."+item[1]+" IS NULL)\n\
BEGIN\n\
Select "+seqname+".NEXTVAL INTO :NEW."+item[1]+"\n\
FROM DUAL;\n\
END;\n/\n"
fidentity.write(createseq)
fidentity.flush()
fidentity.close()
f.close() - 最后,依次执行两个SQL脚本文件。
- 如果有错,那么真是太糟糕啦。根据错误提示,排错吧。 :(
SQL SERVER 2008向ORACLE 11G迁移示例的更多相关文章
- SQL Server 2008创建oracle链接服务器(心得)
操作系统是32位的情况下,曾经没费太多时间创建好了到oracle的链接服务器.主要要点就是: 1.安装oracle精简客户端.当时我用的是版本比较低的“oracle9i310-客户端简化版”,安装好了 ...
- 通过SQL Server 2008 访问Oracle 10g
原文地址:http://www.cnblogs.com/gnielee/archive/2010/09/07/access-oracle-from-sqlserver.html 之前写过一篇关于SQL ...
- SQL Server 2008 R2 Service Pack 3 已经发布
微软SQL Server Product Team在9月26号官方博客宣布,Microsoft SQL Server 2008 R2 Service Pack 3 (SP3)正式发布了 .具体信息可以 ...
- 使用Oracle Sql Developer将SQL SERVER 2008数据库移植到Oracle 11g
ORACLE官方提供的Sql Developer自带的Oracle Migration Workbench. 什么是Oracle SQL Developer?在官方页面上,是这样介绍它的: Oracl ...
- [转]Using the Microsoft Connector for Oracle by Attunity with SQL Server 2008 Integration Services
本文转自:http://technet.microsoft.com/en-us/library/ee470675(v=sql.100).aspx SQL Server Technical Articl ...
- SQL Server 2008通过LinkServer操作ORACLE
时光荏苒~~ 最近项目有需求需要通过SQL Server2008中的数据自动更新到ORACLE中,其实,一开始肯定会想到触发器,因为可以保证实时性. 方案一: 首先,我很确定的一件事情就是MSSQL中 ...
- sql server 2008 r2 中的oracle发布使用笔记
sql server 2008 r2 中的oracle发布功能,能够将oracle数据库作为发布服务器,将oracle中的数据自动同步到sql server 数据库中,在新建oracle发布前确保sq ...
- 使用SQL Database Migration Wizard把SQL Server 2008迁移到Windows Azure SQL Database
本篇体验使用SQL Database Migration Wizard(SQLAzureMW)将SQL Server 2008数据库迁移到 Azure SQL Database.当然,SQLAzure ...
- 【SQL Server数据迁移】64位的机器:SQL Server中查询ORACLE的数据
从SQL Server中查询ORACLE中的数据,可以在SQL Server中创建到ORACLE的链接服务器来实现的,但是根据32位 .64位的机器和软件, 需要用不同的驱动程序来实现. 在64位的机 ...
随机推荐
- [转]simple sample to create and use widget for nopcommerce
本文转自:http://badpaybad.info/simple-sample-to-create-and-use-widget-for-nopcommerce Here is very simpl ...
- TeamTalk源码分析之login_server
login_server是TeamTalk的登录服务器,负责分配一个负载较小的MsgServer给客户端使用,按照新版TeamTalk完整部署教程来配置的话,login_server的服务端口就是80 ...
- UESTC 764 失落的圣诞节 --RMQ/线段树
题意:n种物品,每种物品对不同的人都有不同的价值,有三个人选,第一个为普通学生,第二个是集,第三个是祈,集和祈可以选一样的,并且还会获得加分,集和祈选的普通学生都不能选,问三个人怎样选才能使总分最高. ...
- NOIP2014飞扬的小鸟[DP][WRONG]
坑人啊朴素的dp 75分 用了完全背包才是80分,结果普遍偏小 为什么啊啊啊啊啊 等以后再写一遍吧 #include<iostream> #include<cstdio> #i ...
- Unity打包同一文件Hash不一样
问题起因 游戏开发基本都会涉及到资源版本管理及更新,本文记录我在打包过程中遇到的一小问题: 开过中常用于标记资源版本的方法有计算文件Hash.VCS的版本等. 在Unity中对同一个资源文件进行多次打 ...
- C++在字符串前加一个L作用:
在字符串前加一个L作用: 如 L"我的字符串" 表示将ANSI字符串转换成unicode的字符串,就是每个字符占用两个字节. strlen("asd" ...
- 安装VS2013,可是电脑C盘没空间了,今天早上整理了下
安装VS2013,可是电脑C盘没空间了,今天早上整理了下 安装VS2013,要求C盘有11G的空闲空间,不然不让装, 咋天下好了安装文件,6.89G 今天早上一来, 首先把 一些软件删掉,装到了D盘, ...
- java 27 - 7 反射之 通过反射越过泛型检查
之前学过的集合里面都有泛型,规定了泛型的类型以后,就不能往这个集合添加除了这个类型之外的类型数据了. 那么,有什么方法可以越过这个泛型,添加特定类型以外的类型数据么? 例子: 往ArrayList& ...
- https证书提供商
http://www.itrus.com.cn/verisignchina/About/aboutitrus/Index.html
- Android使用Java Mail API发送邮件
最近在考虑为已经有的一个应用程序增加一个用户反馈的功能,用户可以通过反馈功能将用户的意见和建议.程序出现的问题以一种更符合用户习惯的方式反馈回来.网上也有一些实现好的反馈程序的服务,包括bug的提交. ...