我们正在研究将持久层从Oracle移植到另一个数据库的各种选项,我们正在研究的是MS SQL。但是,我们在整个代码中使用Oracle序列,因此看起来移动将是一个令人头痛的问题。我理解@identity,但这将是对持久性代码的大规模改革。
在SQL Server中是否可以创建一个可以处理序列的函数?
答案 0 :(得分:1)
这取决于您目前在Oracle中使用的序列。通常,在Insert触发器中读取序列。
根据你的问题,我猜是持久层在插入数据库之前生成序列(包括新的pk)
在MSSQL中,您可以将SQL语句与';'组合,以便检索新创建的记录的标识列,使用INSERT INTO ...; SELECT SCOPE_IDENTITY()
因此,插入记录的命令返回一个记录集,该记录集包含单行和包含标识列值的单个列。
你当然可以改变这种方法,并创建序列表(类似于Oracle中的双表),如下所示:
INSERT INTO SequenceTable (dummy) VALUES ('X');
SELECT @ID = SCOPE_IDENTITY();
INSERT INTO RealTable (ID, datacolumns) VALUES (@ID, @data1, @data2, ...)
答案 1 :(得分:1)
我去年在一个项目上这样做了。基本上,我刚刚创建了一个表格,其中包含序列名称,当前值和&增量。
然后我创建了4个触发器:
但是你可能不会欣赏一个限制;功能不能有副作用。所以你可以为GetCurrentSequence(...)创建一个函数,但是GetNextSequence(...)需要是一个proc,因为你可能想要增加当前的序列值。但是,如果它是proc,您将无法在insert语句中直接使用它。
所以而不是
insert into mytable(id, ....) values( GetNextSequence('MySequence'), ....);
相反,你需要将它分解为2行;
declare @newID int;
exec @newID = GetNextSequence 'MySequence';
insert into mytable(id, ....) values(@newID, ....);
此外,SQL Server没有任何可以执行类似
的操作的机制MySequence.Current
或
MySequence.Next
希望有人会告诉我,我对上述限制不正确,但我很确定它们是准确的。
祝你好运。答案 2 :(得分:0)
如果您有很多代码,那么无论如何您都希望对代码进行大规模的改造;在Oracle中运行良好的东西并不总能在MSSQL中运行良好。例如,如果你有很多游标,你可以将它们转换为行到MSSQL,你就不会获得良好的性能。
简而言之,这不是一件容易的事。