中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 数据库开发 > Sybase > 综合技术
如何由Sybase向SQL Server移植数据库
作者:佚名 时间:2007-06-30 14:30 出处:chinaitlab.com 责编:月夜寒箫
              摘要:如何由Sybase向SQL Server移植数据库

最近参与了将一个Sybase数据库移植到Microsoft SQL Server 2000上的项目,我在这一项目上获得的经验,将对Sybase数据库管理员把Sybase数据库移植到SQL Server 2000平台上有一定的帮助。

尽管二者之间的一些差别是相当大的,例如Sybase数据库管理系统中的存储过程在SQL Server就不能被编译,而其它差别则不太大。在完成这一转换前,对脚本文件和存储过程中编程逻辑的行为和结果进行测试是很有必要的。

在下面的部分中,我们将讨论这二种数据库系统之间的一些主要的不同点,在移植的规划阶段,我们必须仔细研究这些区别。

数据兼容模式

对SQL Server 2000和Sybase之间的一些兼容性差别的一个临时性解决方案是改变SQL Server中的数据库兼容性级别,使之与Sybase相符。为此,我们可以使用sp_dbcmptlevel存储过程。

下面表中的语句和结果显示出不同版本数据库之间的差别:

注意:

1、当兼容性模式被设置为70时,下面的词汇不能被用作对象名和标识符:BACKUP、DENY、PRECENT、RESTORE和TOP。

2、当兼容性模式被设置为65时,下面的词汇不能被用作对象名和标识符:AUTHORIZATION、CASCASE、CROSS、DISTRIBUTED、ESCAPE、FULL、INNER、JOIN、LEFT、OUTER、PRIVILEGES、RESTRICT、RIGHT、SCHEMA和WORK。

下面是sp_dbcmptlevel的语法:

 

  
              sp_dbcmptlevel [[@dbname=] name][,[@new_cmptlevel=]version]
              

@dbname是用于检查和改变兼容性水平的数据库名字。

@new_cmptlevel决定数据库被设置的兼容性水平(将它设置为70、65、60,缺省值为NULL)。

例如:

 

  sp_dbcmptlevel pubs
              

这一行代码返回下面的结果:

 

  
              The current compatibility level is 70.(当前的兼容性级别为70。)
              

现在我们来看一下另外一个例子:

 

  
              sp_dbcmptlevel pubs, 65
              

它返回如下的结果:

 

  DBCC execution completed. (DBCC执行结束。)
             
 

如果DBCC打印出错误信息,则需要与系统管理员联系。我们可以使用rerunsp_dbcmptlevel验证pubs数据库是否修改得正确:

 

  
              sp_dbcmptlevel pubs
             
 

它返回下面的结果:

 

  The current compatibility level is 65(当前的兼容性级别为65。)
             

除了上面的例子外,兼容性级别的差别还扩展到了保留字。Sybase和SQL Server都有许多不能被用作数据库中对象名字的的保留字,二种产品的保留字相似,但并不完全相同。

由于能够在Sybase中使用的对象可能不能在SQL Server中使用,这一问题使得由Sybase向SQL Server的移植凭添了许多困难。下面是在SQL Server中是保留字,而在Sybase中不是保留字的词汇清单。

注意:名字为下列清单中词汇的Sybase数据库中的对象在移植到SQL Server数据库时必须换为其它名字。

 

  
              BACKUP COLUMN COMMITTED CONTAINS CONTAINSTABLE
              CROSS CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER
              DENY DISTRIBUTED FILE FLOPPY FREETEXT
              FREETEXTTABLE FULL IDENTITYCOL INNER JOIN
             
 

事务管理模式:

 

  Sybase SQL Server
              
              Set chained [ on : off ] Set implicit_transactions [on : off ]
             
 

在Sybase中使用下面的代码判断事务模式:

 

  
              SELECT @@tranchained
              GO
             
 

下面是可能返回的结果:

0 表明使用的是非链锁式事务模式。

1 表明连接运行在链锁模式下。

在SQL Server中使用下面的代码判断事务模式:

 

  
              IF (@@options & 2) > 0
              PRINT on
              ELSE
              PRINT off
  

下面是可能的返回结果:

 

  
              0 off
              >0 on
             
 

隔离水平

在一个关系数据库这样的多线程应用软件中,数据库引擎对运行的进程间的数据是如何被隔离的管理是非常重要的,在表示隔离水平时,Sybase和SQL Server的语法是不同的。下面的表格表明了Sybase和SQL Server在表示隔离水平时的差别。

 

  
              Sybase SQL Server
              
              0 READ UNCOMMITTED
              1 READ COMMITTED
              2 REPEATABLE READ
              3 SERIALIZABLE
  

游标语法

二种产品中存储过程的创建和执行基本相似,但在移植时,游标语句中的一些例外是我们应当注意的。下面是一个例子:

 

  
              CREATE PROCEDURE sql_cursor AS
              DECLARE @lname char(20), @fname char(20)
              DECLARE mycursor CURSOR FOR
              SELECT au_lname, au_fname FROM authors
              OPEN mycursor
              FETCH FROM mycursor INTO @lname, @fname
              WHILE @@ FETCH_STATUS = 0
              /* Sybase数据库使用@SQLSTATUS而不是@@ FETCH_STATUS */
              BEGIN
              FETCH FROM mycursor INTO @lname, @fname
              /*
              ** 这里应当是一些业务逻辑
              */
              END
              CLOSE mycursor
              DEALLOCATE /* Sybase数据库在这里需要CURSOR这个词 * / mycursor
              
              
              Sybase SQL Server
              
              Fetch命令执行成功 0 0
              Fetch命令执行失败 1 -2
              没有可存取的记录了 2 -1
             

退回触发器

SQL Server中不存在这个命令,因此在向SQL Server移植时,使用了ROLLBACK TRIGGER命令的Sybase存储过程必须被进行修改。在修改带有触发器的数据库表中的数据时,使用ROLLBACK TRIGGER命令容易引起误解,一个ROLLBACK TRIGGER命令只退回触发器以及触发触发器的数据修改,如果已经被提交了,则事务的其它部分会继续,被写到数据库中。因此,事务中的所有语句可能没有被成功地完成,但数据已经被提交了。

下面是Sybase数据库中一个使用ROLLBACK TRIGGER的样例触发器:

 

  
              CREATE TABLE table1 (a int, b int)
              GO
              CREATE TRIGGER trigger1 on table1 FOR INSERT
              AS
              IF EXISTS (SELECT 1 FROM inserted WHERE a = 100)
              BEGIN
              ROLLBACK TRIGGER with RAISERROR 50000 Invalid value for column a
              END
              INSERT INTO table2
              SELECT a, GETDATE() from inserted
              RETURN
              GO
  

在上面的代码中,除非a = 100,则所有插入table1的数据也被作为审计行插入table2中,如果a = 100,ROLLBACK TRIGGER命令被触发,而INSERT命令没有被触发,批命令的其它部分继续执行,这时会出现错误信息,表明在一个INSERT命令中出现了错误。下面是所有的INSERT命令:

 

  
              
              BEGIN TRAN
              INSERT INTO table1 valueS (1, 1)
              INSERT INTO table1 valueS (100,2)
              INSERT INTO table1 valueS (3, 3)
              GO
              SELECT * FROM table1
  

在执行这些命令后,table1和table2二个数据库表将各有2个记录,Table1表中的值为1,1以及3,3,由于ROLLBACK TRIGGER命令,第二个INSERT命令没有执行;Table2表中的值为1,(当前日期)以及3,(当前日期),由于当a = 100时ROLLBACK TRIGGER被触发,触发器中的所有处理被中止,100没有被插入到Table2表中。

在SQL Server中模拟这一操作需要更多的代码,外部的事务必须与保存点同时使用,如下所示:

 

  
              CREATE trigger1 on table1 FOR INSERT
              AS
              SAVE TRAN trigger1
              IF EXISTS (SELECT * FROM inserted WHERE a = 100)
              BEGIN
              ROLLBACK TRAN trigger1
              RAISERROR 50000 ROLLBACK
              END
              INSERT INTO table2
              SELECT a, GETDATE() FROM inserted
              GO
             
 

这一触发器以一个存储点开始,ROLLBACK TRANSACTION只退回触发逻辑,而不是整个事务(规模要小于Sybases数据库中的ROLLBACK TRIGGER语句。对批命令的修改如下:

 

  
              BEGIN TRAN
              SAVE TRAN save1
              INSERT INTO table1 valueS (1, 1)
              IF @@error = 50000
              ROLLBACK TRAN save1
              SAVE TRAN save2
              INSERT INTO table1 valueS (100, 1)
              IF @@error = 50000
              ROLLBACK TRAN save2
              SAVE TRAN save3
              INSERT INTO table1 valueS (3, 3)
              IF @@error = 50000
              ROLLBACK TRAN save3
              COMMIT TRAN
  

我们可以发现,改变不可谓不大。由于ROLLBACK TRIGGER命令能够使任何批命令不能成功执行,因此在移植的SQL Server存储过程代码中必须包括另外的逻辑,根据ROLLBACK TRIGGER的使用,这可能是一个艰巨而必要的任务,没有什么捷径可走。如果在移植后所有的ROLLBACK TRIGGER命令被改变为ROLLBACK TRANSACTION,触发器的执行也会发生变化,因此我们应当十分小心。

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有