Могу ли я поддерживать состояние между вызовами UDF SQL Server? - PullRequest
1 голос
/ 26 августа 2008

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

Я хотел бы добавить скалярную функцию в мой скрипт, которая получает следующий доступный идентификатор (то есть последний использованный идентификатор + 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_, исправил пример кода.

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

Ответы [ 3 ]

2 голосов
/ 27 августа 2008

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

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

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

2 голосов
/ 26 августа 2008

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

sp_getNextID

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

0 голосов
/ 27 августа 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...