【问题标题】:Can I maintain state between calls to a SQL Server UDF?我可以在对 SQL Server UDF 的调用之间维护状态吗?
【发布时间】:2010-09-06 21:30:36
【问题描述】:

我有一个插入数据的 SQL 脚本(通过目前数以千计的 INSERT 语句)其中一列包含一个唯一标识符(虽然不是 IDENTITY 类型,只是一个普通的 ol'int),它实际上在几个不同的表。

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

目前我的脚本如下所示:

声明 @v_baseID int exec dbo.getNextID @v_baseID out --sproc 获取下一个可用的 id --很多这些 - 其中 n 是硬编码值 插入 tableOfStuff (someStuff, uniqueID) 值 ('stuff', @v_baseID + n ) exec dbo.UpdateNextID @v_baseID + lastUsedn --sproc 更新最后使用的id

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

——很多这样 插入 tableOfStuff (someStuff, uniqueID) 值 ('stuff', getNextID() )

硬编码偏移量是一件很痛苦的事,而且容易出错。将它打包成一个简单的标量函数非常吸引人,但我开始认为它不能这样做,因为似乎没有办法维持调用之间的偏移计数器。是这样吗,还是我缺少什么。

我们目前使用的是 SQL Server 2005。

为澄清而编辑:

不会发生两个用户点击它。这是一个升级脚本,只会运行一次,而且不会同时运行。

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

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

【问题讨论】:

    标签: sql sql-server sql-server-2005


    【解决方案1】:

    我开始认为不能那样做,因为似乎没有办法维持调用之间的偏移计数器。是这样吗,还是我遗漏了什么。

    你没有错过任何东西; SQL Server 不支持全局变量,也不支持 UDF 中的数据修改。即使你想做一些像使用 CONTEXT_INFO 一样笨拙的事情(参见 http://weblogs.sqlteam.com/mladenp/archive/2007/04/23/60185.aspx),你也不能在 UDF 中设置它。

    有没有一种方法可以绕过偏移的“硬编码”,通过将其设为变量并循环它的迭代,在该循环中进行插入?

    【讨论】:

      【解决方案2】:

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

      sp_getNextID

      永远不要在 procs 前加上 sp_,这会影响性能,因为优化器首先会检查主数据库以查看该 proc 是否存在于那里,然后再检查本地数据库,如果 MS 决定在服务包中创建 sp_getNextID,您将永远不会被处决

      【讨论】:

        【解决方案3】:

        这可能比它的价值更多,但你可以在 SQL CLR UDF 中使用静态 C#/VB 变量,所以我认为你可以通过每次简单地增加这个变量来做你想做的事情调用 UDF。当然,每当卸载 appdomain 时,静态变量就会丢失。因此,如果您需要 ID 从一天到下一天的连续性,您需要一种方法,在第一次访问 NextId 时,轮询所有使用此 ID 的表,以找到最高值。

        【讨论】:

          猜你喜欢
          • 2011-01-26
          • 1970-01-01
          • 1970-01-01
          • 2012-02-20
          • 2017-01-10
          • 2023-03-07
          • 1970-01-01
          • 1970-01-01
          • 2010-11-29
          相关资源
          最近更新 更多