从Oracle到SQL Server和从SQL Server到Oracle的迁移指南
Posted www.syncnavigator.cn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从Oracle到SQL Server和从SQL Server到Oracle的迁移指南相关的知识,希望对你有一定的参考价值。
SyncNavigator是一款功能强大的数据库同步软件,适用于SQL SERVER, mysql,具有自动/定时同步数据、无人值守、故障自动恢复、同构/异构数据库同步、断点续传和增量同步等功能,支持Windows xp以上所有操作系统,适用于大容量数据库快速同步。
安装包下载地址:https://www.syncnavigator.cn/Setup.zip
帮助文档地址:https://www.syncnavigator.cn/Help_zh-CN.chm
Web文档地址:https://www.syncnavigator.cn/chm/index.htm
创建第一个同步项目
使用 HKROnline SyncNavigator 创建一个数据库同步项目。只需要通过简单的配置,创建完成后您可以随时执行数据库同步任务。
1.点击 “SyncNavigator(Client)” 图标进入系统。
2.在登录界面中输入连接到的服务器地址,点击 “确定” 按钮开始连接。
-
注意:这里不是登陆您的数据库,而是登陆到本软件的管理端。
-
默认情况下直接点击 “连接” 按钮即可(本机默认已经安装)。
-
默认服务器登录用户名为 “admin” 密码为空。
-
本机服务器地址 = 127.0.0.1 。
-
您可以使用域名或者IP地址作为服务器地址。如果指定了端口号可以使用 IP:Port 方式填写。
-
“替换,曾经已经广为人知,无法实现完全的”供应商独立性”。对于数据库而言尤其如此。
企业数据库中使用最多的最大的两个平台是Oracle数据库和Microsoft SQL Server(为替换起见,在本文的其余部分中,我将它们分别称为“ Oracle”和“ SQL Server”)。当然,IBM Db2在不断快速发展的开源替代产品(例如PostgreSQL)正在中低端商品硬件和网站上的动态环境中获得稳固的立足点。
但是,当企业组织需要新的RDBMS时,Oracle与SQL Server是许多业务主管面临的选择。最终的选择基于多个因素:许可证成本,可用的内部专业知识和过去的经验,与现有环境的兼容性,合作伙伴关系,未来的业务计划等。但是,即使进行了最彻底的前期评估和最佳教育决策,有时也要考虑因素更改,然后平台也需要更改。我之所以知道这一点,是因为在我的职业生涯中,我已经进行了两次这样的迁移,一次准备了对过渡互换的评估,并且此时我正在从事跨平台功能的迁移。
Oracle和SQL Server都是“老派”,部分兼容ANSI的RDBMS实现。撇开程序扩展(PL / SQL和Transact-SQL具有不同的语法,但通常在它们之间进行转换)和较新的面向对象的将来排名,SQL代码在外观上看起来很相似。这是一个危险的蜂蜜陷阱。
在Oracle和SQL Server之间进行任何迁移项目(无论在哪个方向上)的两个最关键点是事务,以及密切相关的临时表,它们是解决事务范围的关键工具。 (它们存在于另一个事务的范围内),因为它们是在Oracle中实施用户安全审核的关键部分。但是在SQL Server中,由于用户安全审核
COMMIT
在这种情况下的行为,因此需要一种不同的方法。了解事务结构:从万英尺观察Oracle与SQL Server
Oracle事务是隐式的。这意味着您无需开始交易-您始终处于交易中。并且此事务是开放的,直到您发出commit或rollback语句为止。是的,您可以显式启动事务,定义回滚安全点并设置内部/嵌套事务;但是重要的是,您永远不会“不在事务中”,并且必须始终执行提交或回滚。还要注意,发出数据定义语言(DDL)语句(
CREATE
,ALTER
等) ;在事务中可以通过动态SQL来完成),将在发出该语句的事务中进行提交。与甲骨文不同,SQL服务器具有显式事务。这意味着,除非你明确地开始一个事务,所有的修改将“自动” -immediately致力于为您的语句被处理,因为每个DML语句(
INSERT
,UPDATE
,DELETE
)上创建自己的交易并提交它,除非它的错误了。这是数据存储实现方式不同的结果-数据如何写入数据库以及数据库引擎如何读取数据。
在Oracle中,DML语句直接在数据文件中更改记录。记录的旧副本(如果为,
INSERT
则替换为空的记录)将写入当前的回滚文件,并在记录上标记出更改的更改时间。当
SELECT
发出声明,它是基于发出之前,已修改的数据处理。如果在SELECT
发布后修改 了 任何记录 ,则Oracle使用回滚文件中的旧版本。这就是Oracle实现读取一致性和非阻塞读取/写入的方式。这也是为什么在非常活跃的事务数据库上长时间运行的查询有时会遇到臭名昭著的错误ORA-01555,的原因
snapshot too old: rollback segment ... too small
。(这意味着该记录的较早版本的查询所需要的回滚文件 已被重用。)这就是为什么对“我的Oracle事务应持续多长时间?”这一问题的正确答案。是“只要需要,就不再。”SQL Server的实现有所不同:数据库引擎仅直接向数据文件写入和从中读取数据。每个SQL语句(
SELECT
/INSERT
/UPDATE
/DELETE
)都是事务,除非它是将多个语句组合在一起的显式事务的一部分,从而允许将更改回滚。每个事务都会锁定其所需的资源。当前版本的Microsoft SQL Server在仅锁定所需资源方面进行了高度优化,但是所需内容由SQL代码定义-因此优化查询至关重要。也就是说,与Oracle中不同,SQL Server中的事务应尽可能短,这就是为什么自动提交是默认行为的原因。
Oracle和SQL Server中的哪种SQL构造会受到事务实现方式差异的影响?临时表。
Oracle和SQL Server中的临时表
当ANSI SQL标准定义本地和全局临时表时,它没有明确说明应如何实现它们。Oracle和SQL Server都实现全局临时表。SQL Server还实现了本地临时表。Oracle 18c还实现了“真正的”本地临时表(它们称为“私有临时表”。)这使得SQL Server代码到Oracle 18c的翻译明显比对于旧版本的翻译更简单-完善了Oracle 之前添加的一些相关内容。拥有 像自动递增标识列。
但是从纯功能分析的角度来看,引入私有临时表可能是喜忧参半,因为它使SQL Server到Oracle的迁移问题看起来比实际要少。这是另一个陷阱,因为它可能会带来一些新的挑战。例如,无法在私有临时表上进行设计时代码验证,因此使用它们的任何代码都将总是更容易出错。如果您使用过动态SQL,那么就这样说:私有临时表调试起来同样复杂,但是没有明显的独特用例。因此,为什么Oracle仅在18c中而不是以前在18c中添加本地(专用)临时表。
简而言之,我看不到无法使用相同或更好的全局临时表来实现的Oracle私有临时表的用例。因此,对于任何严重的转换,我们需要了解Oracle和SQL Server全局临时表之间的区别。
Oracle和SQL Server中的全局临时表
Oracle全局临时表是在设计时由DDL语句显式创建的永久数据字典对象。仅当它是数据库级对象时才是“全局”的,并且任何具有所需权限的数据库会话都可以访问它。但是,尽管 全局结构的结构是全局的,但 全局临时表中的所有 数据的作用域仅限于它在其中运行的会话,并且在任何情况下都不在该会话外部可见。换句话说,其他会话可以在同一全局临时表的自己的副本中拥有自己的数据。因此,在Oracle中,全局临时表保存了会话本地数据-大多数用于PL / SQL中以简化代码和优化性能。
在SQL Server中,全局临时表是在Transact-SQL代码块中创建的临时对象。只要它的创建会话处于打开状态,它就存在,并且对数据库中的其他会话可见(无论是结构还是数据)。因此,它是用于跨会话共享数据的全局临时对象。
SQL Server中的本地临时表不同于全局临时表,因为它只能在创建它的会话中访问。与使用全局临时表相比,SQL Server中本地临时表的使用更为广泛(并且,我认为这对数据库性能更为关键 )。
那么,SQL Server中如何使用本地临时表,以及如何将它们转换为Oracle?
SQL Server中本地临时表的关键(正确)用法是缩短或删除事务资源锁定,尤其是:
- 当需要通过某种汇总处理一组记录时
- 何时需要分析和修改数据集
- 需要在同一范围内多次使用同一组数据时
在这些情况下,将记录集选择到本地临时表中以从源表中删除锁定通常是一个更好的解决方案。
值得注意的是,
WITH <alias> AS (SELECT...)
SQL Server中的常用表表达式(CTE,即 语句)仅仅是“语法糖”。在执行SQL之前,它们已转换为内联子查询。Oracle CTE(带有/*+ materialize */
提示)经过性能优化,并创建了物化视图的临时版本。在Oracle的执行路径中,CTE仅访问源数据一次。基于这种差异,SQL Server使用本地临时表而不是对同一个CTE的多个引用可能会更好,就像在Oracle查询中所做的那样。由于事务实现之间的差异,临时表还具有不同的功能。结果,将SQL Server临时表“按原样”移动到Oracle(即使使用Oracle 18c的私有临时表实现)不仅会损害性能,而且在功能上也会出错。
另一方面,从Oracle迁移到SQL Server时,需要注意事务长度,全局临时表的可见性范围以及 带有“物化”提示的CTE块的性能。
在这两种情况下,一旦迁移的代码都包含临时表,我们就不应该谈论代码转换,而应该谈论系统的重新实现。
输入表变量
开发人员可能会想知道:表变量呢?我们是否需要进行任何更改,或者可以在Oracle到SQL Server的迁移步骤中按原样移动表变量?好吧,这取决于为什么以及如何在代码中使用它们。
让我们看看如何同时使用临时表和表变量。我将从Microsoft SQL Server开始。
Transact-SQL中表变量的实现在某种程度上与临时表匹配,但是增加了其自身的某些功能。关键区别在于能够将表变量作为参数传递给函数和存储过程。
这是理论,但实际使用方面的考虑要多一些。
当我来自根深蒂固的Oracle背景时,我首先要进行认真的Transact-SQL优化,所以我希望它是这样的: 表变量 在内存中,而 临时表 在磁盘上。但是我发现直到2014年的Microsoft SQL Server版本都没有在内存中存储表变量。因此,对临时变量进行全表扫描实际上就是对磁盘进行全表扫描。幸运的是,SQL Server 2017和更高版本支持对临时表和表变量进行声明式内存优化。
那么,如果使用临时表也可以做得更好,那么Transact-SQL中表变量的用例是什么?一键属性表变量,它是一个变量,因此不会受事务回滚,可以作为参数传递。
Transact-SQL 函数的限制非常严格:由于函数的任务是返回一些奇异的返回值,因此,按设计,它不会产生替代。Transact-SQL甚至
SELECT
认为是替代,因为在SQL Server中对表的任何访问这意味着在函数内部,我们无法访问现有临时表中的数据,也无法创建临时表。结果,如果我们需要将任何记录集传递给函数,则必须使用表变量。Oracle使用(一系列)临时表和集合变量(与Transact-SQL表变量的Oracle PL / SQL等效)的注意事项有所不同。Oracle集合变量在内存中,而临时表放在临时表空间中。Oracle函数允许对永久或临时表的访问;
SELECT
Oracle中的简单方法永远不会锁定资源。在Oracle中,使用集合变量还是临时表的选择取决于预期的数据量,需要保留此数据的持续时间以及内存与磁盘的分配和可用性。同样,集合变量是将行集作为输出返回到主机程序的标准方法。
由于大多数SQL语法元素在SQL Server和Oracle之间看起来非常相似,因此将具有表变量的代码块从SQL Server Transact-SQL转换为Oracle PL / SQL是一个更简单且在语法上更为合理的过程。它可以通过基本的验证测试,但是在功能上是正确的,除非采用了替代的临时表重新实现步骤。替换,从Oracle移到SQL Server的代码涉及更多的修改步骤,只是为了使语法有效。为了使功能正确,还需要解决使用临时表和CTE的深度问题。
内部交易(“嵌套交易”)
在从Oracle到SQL Server的迁移挑战方面,下一个要研究的主要领域是嵌套事务。
就像临时表一样,如果Transact-SQL代码包含任何嵌套的事务或不嵌套的事务,或者Oracle代码包括任何嵌套的事务,则我们所讨论的不仅是简单的代码迁移,还包括功能的重新实现。
首先,让我们看一下Oracle合并事务的行为以及我们如何使用它们的方式。
Oracle中的嵌入式事务
在常规的并行Oracle SQL查询中,嵌套事务没有实际用途。当您以交互方式使用Oracle时,只要看到状态就可以手动提交更改。如果您所做的一些更改,直到完成最后一个操作(例如,对您来说不确定),您才能提交这些更改,但可能需要回滚,但您想保留已经完成的工作,您将创建一个安全点以回滚到该安全点,而无需提交或回滚整个事务。
那么,在哪里使用重组事务?在PL / SQL代码中。更简化,在自治程序中-用声明的程序
PRAGMA AUTONOMOUS_TRANSACTION
。这意味着,当调用此代码(作为命名存储过程或匿名方式)时,将独立于发起此代码的事务来提交或回退事务。使用内部事务的目的是使独立的工作单元恢复提交或回滚,而不管调用代码将如何处理。当内部事务可以提交或回滚时,用来进行检查(或替代)共享资源的可用性(例如在实施房间预订系统时)。仅提交内部事务的主要用途是活动监视,代码跟踪和安全访问审核(即,允许用户尝试更改,但试图这样做)。
SQL Server Transact-SQL代码中的嵌入事务完全不同。
SQL Server中的嵌套事务
在Transact-SQL中,内部事务是否完全提交属于最外部的事务。如果内部事务已回滚,则只是回滚。但是,如果内部事务已提交,则它仍未完全提交,因为如果外部事务的任何等级的事务都可以回滚,则可以回滚。
因此,如果可以通过回滚外部事务来撤消其提交,那么内部事务有什么用?答案与本地临时表的用例相同:释放对资源的锁定。直接在“父”)事务范围内的锁。在复杂的Transact-SQL代码中使用它来释放外部事务的内部资源。这是一种性能优化和资源管理工具。
由于Oracle和SQL Server内部/嵌套事务具有不同的(有时甚至相反的)行为和完全不同的用例,因此从一个平台迁移到另一个平台既需要重新编写,而且还需要完全重新构造任何包含嵌套事务块的作用域。
其他因素
这些临时表和以事务为中心的考虑是否是从Oracle到SQL Server迁移中唯一需要解决的问题?而且它们可能是最重要的,但肯定还有其他人,每个人都有自己的怪癖值得一提。以下是我发现的最容易误解的主题:
- SQL Server中的身份列
- Oracle中的序列
- Oracle中的名词
- 筛选索引
- 读取一致性(仅从Oracle到SQL Server)
- 使用迁移工具
本系列的下一部分将继续探讨这些内容,尤其是前三个部分。
临时表,表/集合变量和合并事务:前三项迁移痛苦点
我从临时表,表变量/集合和合并事务开始,因为它们是转换项目中最常见,最明显的故障点。Oracle数据库或Microsoft SQL Server中的任何重要系统必然都将使用其中的一些,并且使用这些元素与相应的RDBMS实现的事务支持的特定设计紧密结合。
以上是关于从Oracle到SQL Server和从SQL Server到Oracle的迁移指南的主要内容,如果未能解决你的问题,请参考以下文章
标准脚本数据库变量(Oracle 与 Sql Server 术语)
创建 SSIS 包 - 将数据从 Oracle 复制到 SQL Server