序列(Sequence)是Oracle数据库中独有的,由于在项目中使用Sequence生成的数据做为主键,所以必须有一套完整可行的转换方案来替代。

涉及到的程序应该改动尽可能的小。

我们应该提供一个跟Oracle数据库取序列方法差不多的函数,来缓解由于数据库不同,导致的额外工作量。

这里我们来看一下微软的解决方案。

使用到的工具为Microsoft SQL Server Migration Assistant 2005 for Oracle(以下简称SSMA)

该工具可以从微软网上免费下载。

 

在源数据库Oracle中建立一个测试数据库TestDB_Seq,里面只有一个序列Seq_Test

在目标数据库SQLServer中建立一个空数据库TestDB_Ssq。

 

之后我们将两个数据库加载到SSMA中 Convert Schema一下

 

image

 

这里我们还可以在Type Mapping 中看到微软对两种不同数据库之间,提供的数据类型解决方案

image

这里,Oracle中的序列最终被生成到dbo的Sequence Emulations中

image

 

 

右键SQLServer数据源中的SEQ_TEST,选择Synchronize with Database

image

点击OK,就完成了使用SSMA对Sequence的移植。

 

下面我们来看看SQLServer中到底发生了什么。

image

在表里面,对应的生成了一个名为$SSMA_seq_SEQ_TEST的表。

表中只有一个ID字段,类型为numeric(38,0),非空,自增

同时在存储过程中生成了一个名为$SSMA_sp_get_nextval_SEQ_TEST的存储过程。

 

 

执行该存储过程,通过参数curval,我们就可以每次得到一个不同的增量。

以下为存储的内容和执行的结果。

 

1 set ANSI_NULLS ON
2 set QUOTED_IDENTIFIER ON
3 go
4 
5 ALTER proc [dbo].[$SSMA_sp_get_nextval_SEQ_TEST] @curval numeric(38,0) out as insert [dbo].[$SSMA_seq_SEQ_TEST] default values set @curval = scope_identity()

 

 

image

 

好吧,文章就到这里,相信你也看到了微软对不同数据库之间转移的解决方案,希望上面存储过程里面的代码,会对你有所帮助。

 

BTW:终于明白前辈们为什么这样写代码

public User BuildUser()
{
    User.ID = getSEQ("SEQ_USer");
    User.Name = "Gavin";
}

 

当时天真的认为,这样生成实体的话,在Insert操作时候,需要连接两次数据库,一次用来读取ID,另一次执行Insert操作。

不如不给User.ID赋值,直接在Insert语句中使用SEQ_User.nextval。惭愧,惭愧!

posted on 2010-04-26 20:26  C.Gavin  阅读(1885)  评论(1编辑  收藏  举报