是否可以在 SQL Server 中创建一个可以处理序列的函数?

Posted

技术标签:

【中文标题】是否可以在 SQL Server 中创建一个可以处理序列的函数?【英文标题】:Is it possible in SQL Server to create a function which could handle a sequence? 【发布时间】:2008-11-27 16:30:14 【问题描述】:

我们正在研究将持久层从 Oracle 移植到另一个数据库的各种选项,我们正在研究的一个是 MS SQL。但是,我们在整个代码中使用 Oracle 序列,因此移动似乎会让人头疼。我了解@identity,但这将是对持久性代码的大规模检修。

【问题讨论】:

【参考方案1】:

这取决于您当前在 Oracle 中使用的序列。通常在插入触发器中读取一个序列。

从你的问题我猜是持久层在插入数据库之前生成序列(包括新的pk)

在 MSSQL 中,您可以将 SQL 语句与 ';' 组合在一起,因此要检索新创建记录的标识列,请使用 INSERT INTO ... ;选择 SCOPE_IDENTITY()

因此,插入记录的命令返回一个记录集,其中包含单行和单列,其中包含标识列的值。

您当然可以改变这种方法,并创建序列表(类似于 Oracle 中的双表),如下所示:

INSERT INTO SequenceTable (dummy) VALUES ('X');
SELECT @ID = SCOPE_IDENTITY();
INSERT INTO RealTable (ID, datacolumns) VALUES (@ID, @data1, @data2, ...)

【讨论】:

【参考方案2】:

我去年在一个项目上做了这个。基本上,我只是创建了一个包含序列名称、当前值和增量数量的表。

然后我创建了 4 个过程:

GetCurrentSequence(sequenceName) GetNextSequence(sequenceName) CreateSequence(sequenceName, startValue, incrementAmount) 删除序列(序列名称)

但是有一个你可能不理解的限制;函数不能有副作用。因此,您可以为 GetCurrentSequence(...) 创建一个函数,但 GetNextSequence(...) 需要是一个 proc,因为您可能希望增加当前序列值。但是,如果它是 proc,您将无法直接在插入语句中使用它。

所以不是

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

希望有人会告诉我上述限制是不正确的,但我很确定它们是准确的。

祝你好运。

【讨论】:

【参考方案3】:

如果您有很多代码,那么无论如何您都会想要对代码进行大规模的检查;在 Oracle 中运行良好的东西并不总是在 MSSQL 中运行良好。例如,如果您有很多游标,虽然您可以将它们逐行转换为 MSSQL,但您不会获得良好的性能。

简而言之,这不是一件容易的事。

【讨论】:

以上是关于是否可以在 SQL Server 中创建一个可以处理序列的函数?的主要内容,如果未能解决你的问题,请参考以下文章

确定用户在 SQL Server 中创建的对象

如何在 SQL Server 中创建自定义动态数据掩码函数?

在 Visual Studio 数据库项目/SQL Server 中创建默认数据

我可以在 SQL Server 的添加列语句中创建命名默认约束吗?

sqlserver中创建一个表对象应该包括哪两个步骤?

使用 Polybase 在 SQL Server 2016 中创建外部表的问题