序列(Sequence)是Oracle数据库中独有的,由于在项目中使用Sequence生成的数据做为主键,所以必须有一套完整可行的转换方案来替代。
涉及到的程序应该改动尽可能的小。
我们应该提供一个跟Oracle数据库取序列方法差不多的函数,来缓解由于数据库不同,导致的额外工作量。
这里我们来看一下微软的解决方案。
使用到的工具为Microsoft SQL Server Migration Assistant 2005 for Oracle(以下简称SSMA)
该工具可以从微软网上免费下载。
在源数据库Oracle中建立一个测试数据库TestDB_Seq,里面只有一个序列Seq_Test
在目标数据库SQLServer中建立一个空数据库TestDB_Ssq。
之后我们将两个数据库加载到SSMA中 Convert Schema一下
这里我们还可以在Type Mapping 中看到微软对两种不同数据库之间,提供的数据类型解决方案
这里,Oracle中的序列最终被生成到dbo的Sequence Emulations中
右键SQLServer数据源中的SEQ_TEST,选择Synchronize with Database
点击OK,就完成了使用SSMA对Sequence的移植。
下面我们来看看SQLServer中到底发生了什么。
在表里面,对应的生成了一个名为$SSMA_seq_SEQ_TEST的表。
表中只有一个ID字段,类型为numeric(38,0),非空,自增
同时在存储过程中生成了一个名为$SSMA_sp_get_nextval_SEQ_TEST的存储过程。
执行该存储过程,通过参数curval,我们就可以每次得到一个不同的增量。
以下为存储的内容和执行的结果。
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()
好吧,文章就到这里,相信你也看到了微软对不同数据库之间转移的解决方案,希望上面存储过程里面的代码,会对你有所帮助。
BTW:终于明白前辈们为什么这样写代码
1
2
3
4
5
|
public User BuildUser() { User.ID = getSEQ( "SEQ_USer" ); User.Name = "Gavin" ; } |
当时天真的认为,这样生成实体的话,在Insert操作时候,需要连接两次数据库,一次用来读取ID,另一次执行Insert操作。
不如不给User.ID赋值,直接在Insert语句中使用SEQ_User.nextval。惭愧,惭愧!