Могу ли я сохранять состояние между вызовами UDF SQL Server?

StackOverflow https://stackoverflow.com/questions/28280

  •  09-06-2019
  •  | 
  •  

Вопрос

У меня есть сценарий SQL, который вставляет данные (с помощью операторов INSERT, число которых в настоящее время исчисляется тысячами). Один из столбцов содержит уникальный идентификатор (хотя и не тип IDENTITY, а просто старый int), который на самом деле уникален для нескольких разных таблиц.

Я хотел бы добавить в свой сценарий скалярную функцию, которая получает следующий доступный идентификатор (т. е.последний использованный идентификатор + 1), но я не уверен, что это возможно, потому что, похоже, нет способа использовать глобальную или статическую переменную из UDF, я не могу использовать временную таблицу, и я могу t обновлять постоянную таблицу изнутри функции.

На данный момент мой скрипт выглядит так:

   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.

правки для пояснения:

Попадания двух пользователей не произойдет.Это сценарий обновления, который будет запускаться только один раз и никогда одновременно.

Фактическая процедура не имеет префикса sp_, исправлен пример кода.

При обычном использовании мы используем таблицу идентификаторов и процедуру для получения идентификаторов по мере необходимости. Я просто искал более простой способ сделать это в этом сценарии, который, по сути, просто сбрасывает кучу данных в базу данных.

Это было полезно?

Решение

Я начинаю думать, что это невозможно сделать, поскольку, похоже, нет способа поддерживать счетчик смещения между вызовами.Это правда, или я что-то упускаю.

Вы ничего не упускаете;SQL Server не поддерживает глобальные переменные и не поддерживает изменение данных внутри UDF.И даже если вы хотите сделать что-то столь же неуклюжее, как использование CONTEXT_INFO (см. http://weblogs.sqlteam.com/mladenp/archive/2007/04/23/60185.aspx), вы все равно не сможете установить это из UDF.

Есть ли способ обойти «жесткое кодирование» смещения, сделав его переменной и зацикливая ее итерацию, выполняя вставки внутри этого цикла?

Другие советы

Если у вас есть два пользователя, которые нажимают на него одновременно, они получат один и тот же идентификатор.Почему вместо этого вы не использовали таблицу идентификаторов с идентификатором, вставили в нее и использовали ее как уникальный (гарантированный) идентификатор, это также будет работать намного быстрее

sp_getNextID

никогда не префиксируйте процедуры с помощью sp_, это влияет на производительность, потому что оптимизатор сначала проверяет главную БД, чтобы увидеть, существует ли эта процедура там, а затем локальную БД, а также, если MS решит создать sp_getNextID в пакете обновления, ваш никогда не будет выполнен

Вероятно, это потребует больше работы, чем того стоит, но вы можете использовать статические переменные C#/VB в UDF SQL CLR, поэтому я думаю, что вы сможете делать то, что хотите, просто увеличивая эту переменную каждый раз, когда UDF называется.Разумеется, статическая переменная будет потеряна при каждой выгрузке домена приложения.Поэтому, если вам нужна непрерывность вашего идентификатора от одного дня к другому, вам понадобится способ при первом доступе к NextId опросить все таблицы, которые используют этот идентификатор, чтобы найти наибольшее значение.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top