Вставить процесс не удалось, хотя мы проверяем, что существует первым - PullRequest
2 голосов
/ 04 апреля 2011
ALTER PROCEDURE [dbo].[spWeb_TransactionProjectUpdate]
    @transactionId              INT,
    @projectId                  INT
AS

IF NOT EXISTS(SELECT * FROM dbo.com_project_transaction_link WHERE pt_tr_transaction_id = @transactionId AND pt_pj_project_id = @projectId)
BEGIN

    INSERT INTO dbo.com_project_transaction_link(pt_tr_transaction_id, pt_pj_project_id) VALUES (@transactionId, @projectId)

END

Таким образом, когда мы запускаем эту процедуру после того, как идентичная запись уже есть в базе данных, происходит сбой. Но у нас есть IF NOT EXISTS именно по этой причине. Зачем его пытаться вставить, если он находит запись?

1 Ответ

1 голос
/ 04 апреля 2011

Если эта пара столбцов (pt_tr_transaction_id, pt_pj_project_id) уникальна, почему бы просто не поместить в эти два столбца УНИКАЛЬНЫЙ ИНДЕКС?Объедините это с параметром IGNORE_DUP_KEY для этого индекса, и у вас будет индекс, который

  • предотвращает вставку любых дубликатов
  • не препятствует (исключение выброса), когдаобнаружен дубликат - он просто молча проглатывается

Эта ваша проверка склонна к сбою, поскольку вы ничего не делаете, чтобы два клиента не запускались одновременно;оба могут сначала проверить, существует ли эта строка, и получить обратно false, а затем оба могут продолжить вставку этих значений.Ваша проверка не защищена от одновременного выполнения.

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