2009-02-24 3 views
1

Я долгое время являюсь пользователем Firebird, и у него есть функция Generators (я думаю, что Oracle также имеет ее, и она называется Sequences). Я новичок в SQL Server, и мне нужно имитировать ту же функцию. Я не могу использовать поле идентификации для решения моей проблемы. Мне нужна именованная серия значений, а не уникальный номер для каждой строки.Лучший способ сделать сериализуемые обновления для таблицы

Моя самая большая проблема заключалась в том, что несколько пользователей одновременно вызывали эту процедуру и получали дублированные значения, поэтому я решил заблокировать, используя уровень изоляции SERIALIZABLE.

Так что я придумал этот код (я использую SQL Server 2005):

CREATE TABLE dbo.GENERATORS 
    (
     [NAME] VARCHAR(30) NOT NULL, 
     [VALUE] INT, 
     CONSTRAINT UNQ_GENERATORS_NAME UNIQUE NONCLUSTERED ([NAME]) 
    ) 
GO 

CREATE PROCEDURE GEN_ID 
    (
     @GENERATOR_NAME VARCHAR(30) 
    ) 
AS 
    DECLARE @RETURN_VALUE INT ; 
    SET NOCOUNT ON 
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 
    BEGIN TRANSACTION 
    UPDATE GENERATORS 
    SET  [VALUE] = [VALUE] + 1 
    WHERE [NAME] = @GENERATOR_NAME 
    IF @@ROWCOUNT = 0 
     BEGIN 
      INSERT INTO dbo.GENERATORS ([NAME], [VALUE]) 
      VALUES (@GENERATOR_NAME, 1) 
      SET @RETURN_VALUE = 1 
     END 
    ELSE 
     BEGIN 
      SELECT @RETURN_VALUE = [VALUE] 
      FROM GENERATORS 
      WHERE [NAME] = @GENERATOR_NAME 
     END 
    COMMIT TRANSACTION 
    RETURN @RETURN_VALUE 
GO 

Так что мои вопросы:

  • Является ли это хорошее решение?
  • Есть ли лучший способ?

Спасибо.

ответ

2

Вместо UPDATE и SELECT, чтобы получить значение назад, что вы только что добавили, вы можете сделать

UPDATE GENERATORS 
SET  @RETURN_VALUE = [VALUE] = [VALUE] + 1 
WHERE [NAME] = @GENERATOR_NAME 

, который может устранить необходимость в уровне изоляции

Я предпочел бы вернуться @RETURN_VALUE, как параметр OUTPUT, а не как возвращаемое значение - оставляя возвращаемое значение свободным для любого кода ошибки во время выполнения.

+0

Это очень приятно, спасибо большое. –

Смежные вопросы