我有一个插入数据的SQL脚本(通过当前编号为数千的INSERT语句)其中一列包含一个唯一的标识符(虽然不是IDENTITY类型,只是一个普通的ol'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中。
答案 0 :(得分:2)
如果有2个用户同时点击它们,它们将获得相同的ID。你为什么不使用带有身份的id表,插入并使用它作为唯一(保证)id,这也会表现得更快
sp_getNextID
永远不会使用sp_为procs添加前缀,这具有性能影响,因为优化器首先检查主数据库以查看该进程是否存在,然后是本地数据库,如果MS决定在服务包中创建sp_getNextID,那么它将永远不会执行
答案 1 :(得分:2)
我开始认为不能这样做,因为似乎没有办法维持调用之间的偏移计数器。这是对的,还是我缺少的东西。
你没有遗漏任何东西; SQL Server不支持全局变量,并且它不支持UDF中的数据修改。即使你想像使用CONTEXT_INFO(参见http://weblogs.sqlteam.com/mladenp/archive/2007/04/23/60185.aspx)那样做一些事情,也无法在UDF中设置它。
有没有办法可以绕过偏移量的“硬编码”,使变量循环并迭代迭代,在该循环中进行插入?
答案 2 :(得分:0)
它可能比它的价值更多,但你可以在SQL CLR UDF中使用静态C#/ VB变量,所以我认为你只需每次增加这个变量就可以做你想做的事情。调用UDF。当然,每当appdomain卸载时,静态变量都会丢失。因此,如果您需要从一天到下一天持续使用您的ID,那么在第一次访问NextId时,您需要一种方法来轮询使用此ID的所有表,以找到最高值。