Генерация уникальных идентификаторов и преобразование уникального идентификатора в TSQL

#tsql #syntax #uniqueidentifier

#tsql #синтаксис #uniqueidentifier

Вопрос:

Я пытаюсь обновить таблицу SQL, создав два новых значения столбца: уникальный идентификатор, а затем сокращенную целочисленную версию того же уникального идентификатора, который только что был создан.

Используя трюк, который я нашел здесь (см. «Путь NEWID ()» внизу), я думал, что это сработает :

 Update Customer Set [UniqueId] = NEWID(), [UniqueIntegerId] = ABS(CAST(CAST([UniqueId] AS VARBINARY) AS INT))
  

но это генерирует что-то вроде

[UniqueID] [UniqueIntegerId]

3C79 …5A4DEB2 754988032

1FD6 …828B943 754988032

1F48 …E80F511 754988032 <— повторяется! не хочу!

Какой синтаксис правильный для попытки выполнить это?

Комментарии:

1. Я вижу повторы только тогда, когда я использую NEWSEQUENTIALID , а не NEWID на какой версии SQL Server вы работаете? Я полагаю, это постоянный бит для MAC-адреса?

2. Версия Microsoft SQL Server 2008 (SP1).

3. Хотя на самом деле мой тест insert не был обновлен. Уверен, что ваше обновление будет работать с версией столбца «до» [UniqueId] , а не с версией «после».

4. @MartinSmith: Действительно, так и будет, как подтверждает эта статья .

Ответ №1:

Это не будет работать так, как ожидалось, потому [UniqueId] что в выражении вычисляется значение перед обновлением. Это то, что вы могли бы попробовать вместо этого:

 DECLARE @uid uniqueidentifier;
UPDATE Customer
SET
  @uid = [UniqueId] = NEWID(),
  [UniqueIntegerId] = ABS(CAST(CAST(@uid AS VARBINARY) AS INT))
  

@uid Переменной присваивается то же значение, [UniqueId] что и и затем используется вместо [UniqueId] в выражении для другого столбца.

Комментарии:

1.Я не думаю, что здесь можно полагаться на оценку слева направо. Похоже на If there are multiple assignment clauses in a single SELECT statement, SQL Server does not guarantee the order of evaluation of the expressions. Note that effects are only visible if there are references among the assignments. ссылку

2. @Martin: Спасибо за ссылку. Я согласен, это действительно похоже. Тем не менее, я уверен, что такие вещи должны быть явно указаны в соответствующей статье документа, что, похоже, не делается в отношении обновлений такого рода. ИМХО, это просто еще одна темная область, похожая на необычные обновления (если я не неправильно истолковываю термин, и это ОБНОВЛЕНИЕ тоже квалифицируется как необычное обновление). Я имею в виду, что надежность обновлений quirky официально не подтверждена и не опровергнута. В результате люди бесконечно спорят «за» и «против» по этому вопросу, находя косвенные доказательства в официальных источниках или пытаясь доказать свою точку зрения эмпирическим путем.

3. (Под «бесконечным» я подразумеваю, что люди, похоже, не убеждены аргументами других людей, поэтому общая неопределенность сохраняется.)

4. В основном Джефф Моден! Вероятно, в этом случае было бы лучше создать UniqueIntegerId вычисляемый столбец, чтобы избежать каких-либо сомнений.

5. @Martin: Когда я впервые прочитал вашу идею о вычисляемом столбце, я подумал, что это хорошо, но это было только сначала. Теперь, после повторного прочтения вопроса, я все больше и больше склоняюсь к тому, чтобы согласиться с вами, что это, вероятно, лучшее решение, так что … мм? (То есть, «как насчет публикации этого в качестве ответа’?)