我可以在两次调用SQL Server UDF之间保持状态吗?

时间:2020-03-05 18:43:21  来源:igfitidea点击:

我有一个SQL脚本,用于插入数据(通过INSERT语句,当前编号为数千),其中一列包含一个唯一的标识符(尽管不是IDENTITY类型,只是一个普通的int),实际上在几个不同的表中是唯一的。

我想在我的脚本中添加一个标量函数,以获取下一个可用的ID(即上次使用的ID + 1),但是我不确定这是否可行,因为似乎没有使用全局或者从UDF内部获取静态变量,我无法使用临时表,也无法从函数内部更新永久表。

目前,我的脚本如下所示:

declare @v_baseID int 
   exec dbo.getNextID @v_baseID out  --sproc to get the next available id
   --Lots of these - where n is a hardcoded value
   insert into tableOfStuff (someStuff, uniqueID) values ('stuff', @v_baseID + n ) 
   exec dbo.UpdateNextID @v_baseID + lastUsedn  --sproc to update the last used id

但我希望它看起来像这样:

--Lots of these
   insert into tableOfStuff (someStuff, uniqueID) values ('stuff', getNextID() )

对偏移量进行硬编码是一个麻烦,而且容易出错。将其打包成一个简单的标量函数非常吸引人,但是我开始认为不能那样做,因为似乎没有办法在调用之间保持偏移量计数器。是的,还是我想念的东西。

目前,我们正在使用SQL Server 2005.

编辑以澄清:

不会有两个用户点击它。这是一个升级脚本,将只运行一次,并且永远不会同时运行。

实际的sproc没有以sp_为前缀,修复了示例代码。

在正常使用中,我们确实使用id表和sproc根据需要获取ID,我只是在寻找一种更干净的方法来执行此脚本,该脚本实际上只是将一堆数据转储到db中。

解决方案

回答

如果我们有2个用户同时点击它,他们将获得相同的ID。为什么不使用带有标识的id表,而是将其插入并使用它作为唯一的(保证的)id,这样做也会更快

sp_getNextID

永远不会在proc前面加上sp_前缀,这对性能有影响,因为优化器首先检查主数据库以查看该proc是否存在,然后再检查本地DB,而且如果MS决定在服务包中创建sp_getNextID,则我们将永远不会执行

回答

这可能比它值得的工作还多,但是我们可以在SQL CLR UDF中使用静态C#/ VB变量,因此我认为我们可以通过每次UDF每次简单地增加此变量就可以完成我们想做的事情叫。当然,只要卸载appdomain,静态变量就会丢失。因此,如果我们需要一天到一天的ID连续性,则需要一种在首次访问NextId时轮询使用该ID的所有表以找到最高价值的方法。

回答

I'm starting to think it can't be done that way since there doesn't seem to be a way to maintain the offset counter between calls. Is that right, or is there something I'm missing.

我们什么都不会错过; SQL Server不支持全局变量,也不支持UDF中的数据修改。而且,即使我们想做一些像使用CONTEXT_INFO一样的笨拙操作(请参阅http://weblogs.sqlteam.com/mladenp/archive/2007/04/23/60185.aspx),也无法从UDF内进行设置反正。

有没有一种方法可以通过使变量成为变量并遍历其迭代,然后在该循​​环中进行插入来解决偏移量的"硬编码"?