2014-02-18 3 views
1

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

Ниже мой стол:

CREATE TABLE tblTransactions 
    (
    dctransno  INT IDENTITY PRIMARY KEY, 
    vcDescription VARCHAR, 
    dcTransNoCopy INT NULL, 
    user   VARCHAR   
) 

и мой запрос:

BEGIN TRAN 

INSERT INTO tblTransactions 
      (dctransno, 
      user) 
VALUES  (@vcDescription, 
      @user); 

SET @identity = @@IDENTITY -- get the identity 

UPDATE tblTransactions 
SET dcTransNoCopy = @identity 
WHERE dcTransNo = @identity 
     AND user = @user; -- insert 

COMMIT TRAN 

То, что я хочу, чтобы добиться того, что я могу иметь сгруппированных сделку, как показано ниже. Например, Проблема в том, что мой вышеприведенный запрос не имеет права собственности. Предполагая, что пользователь A и userB одновременно используют систему:

 dcTransNo  Description  dcTransNoCopy  User 
      1   Transaction1  1    userA 
      2   Transaction2  1    userA 
      3   Transaction3  1    userA 
      4   Transaction1  3    userB  ---> not correct, ClonetransNo value for userB should be 4 not 3. 

Пожалуйста, помогите, заблаговременно.

+0

Я предполагаю, что dcTransNoCopy является CloneTransNo и dcTransNo просто TransNo? В ваших образцовых данных и в поставляемом коде используются разные имена. Кроме того, если вы используете scope_identity(), это решает проблему? Я подозреваю, что это будет – billinkc

+0

Да, извините dcTransNoCopy - это CloneTransNo и dcTransNo - это просто TransNo. – popoyjin

+0

Код, который вы нам указали 'SET dcTransNoCopy = @identity WHERE dcTransNo = @ identity' никогда не может привести к' 4,3'. Оба столбца всегда будут иметь одинаковое значение. –

ответ

1

Вы должны использовать SCOPE_IDENTITY() вместо @@ IDENTITY

Дополнительная информация here

+0

Привет, bhs, я уже пробовал использовать scope_identity, поэтому я перешел на идентификатор @@, но ранее не добавлял начальный переход в свой запрос. Я посмотрю, что произойдет. Кстати, спасибо за быстрый ответ. – popoyjin

+0

никаких проблем - scope_identity() для этой цели, хотя поэтому она должна работать :-) – bhs

0

Почему вы не используете выходной таблицы?

DECLARE @InsertedRows TABLE (ProductID INT, ProductNumber NVARCHAR(25)) 
INSERT Product ([Name], ProductNumber, ListPrice) 
OUTPUT inserted.ProductID, inserted.ProductNumber 
INTO @InsertedRows 
SELECT [Name], ProductNumber, ListPrice 
FROM ProductsToInsert AS I 
WHERE NOT EXISTS (SELECT 1 FROM Product WHERE ProductNumber = I.ProductNumber) 

UPDATE ProductsToInsert 
SET InsertedIdentityValue = T.ProductID 
FROM ProductsToInsert I 
JOIN @InsertedRows T ON T.ProductNumber = I.ProductNumber 

SELECT RowID, ProductNumber, InsertedIdentityValue 
FROM ProductsToInsert 
WHERE InsertedIdentityValue IS NOT NULL 

это от http://www.sqlteam.com/article/using-the-output-clause-to-capture-identity-values-on-multi-row-inserts

+0

Привет, Mathese, спасибо за это, не знали о выходе. Заменяет ли это scope_identity() эффективный захват идентификатора внутри транзакции? – popoyjin

+0

Здравствуйте, да, вам больше не нужно использовать scope_identity. Microsoft классифицирует способ поиска идентичности следующим образом: @@ идентичность небезопасна внутри одного и того же pid, scope_identifie небезопасна с разными pid, наилучшая практика вывода. Взгляните на статью, из которой она исходит :) –

+0

Теперь я меняю свой запрос на результат. Будет следить за результатами. Большое спасибо! – popoyjin

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