Попытка обновить строку с помощью 3 первичных ключей не работает

#sql #sql-server #tsql

#sql #sql-сервер #tsql

Вопрос:

У меня есть таблица с 3 первичными ключами для строки, и всякий раз, когда я пытался обновить эту строку, я получаю «Не удается вставить повторяющиеся значения», но я пытаюсь обновить эту строку с помощью команды ОБНОВЛЕНИЯ, а не ВСТАВИТЬ?

 CREATE TABLE dbo.TestData
(
    OgrId int NOT NULL,
    StrId int NOT NULL,
    UserId int NOT NULL,
    ProductId int NOT NULL,
    CONSTRAINT PK_OgrId_StrId_UserId
        PRIMARY KEY(OgrId, StrId, UserId)
)

DECLARE @ogrId int = 99;
DECLARE @strId int = 44;
DECLARE @userId int = 1223;
DECLARE @id int = 14;

DECLARE @querySelect int = 
    (SELECT ProductId FROM dbo.TestData
        WHERE
            OgrId = @ogrId AND 
            StrId = @strId AND 
            UserId = @userId AND
            ProductId= @id);
IF @querySelect IS NULL
    BEGIN
        INSERT INTO dbo.TestData(OgrId, StrId, UserId, ProductId)
        VALUES (@ogrId , @strId , @userId, @id);
    END
ELSE
    BEGIN
        UPDATE dbo.TestData
        SET ProductId= @id
        WHERE 
            OgrId = @ogrId AND 
            StrId = @strId AND 
            UserId = @userId;
    END
 

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

1. У вас не может быть «3 первичных ключа», первичный ключ может быть только один. То, что у вас есть, состоит из PK с 3 ключевыми полями

2. >>> я пытаюсь обновить эту строку с помощью UPDATE<<< В вашем коде тоже есть команда insert: INSERT INTO dbo.TestData(OgrId, StrId, UserId, ProductId) VALUES (@ogrId , @strId , @userId, @id);

3. Существует также оператор if , который выбирает update или insert … И у меня может быть 3 первичных ключа, вот в чем дело!

4. Ничто не может помочь тому, у кого есть «3 первичных ключа»

5. Я уже исправил это, спасибо за ответы 🙂

Ответ №1:

Ваша проблема в том, что вы на самом деле вызываете не ОБНОВЛЕНИЕ, а ВСТАВКУ, которая пытается создать дубликат ключа.

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

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

 CREATE TABLE dbo.TestData
(
    OgrId int NOT NULL,
    StrId int NOT NULL,
    UserId int NOT NULL,
    ProductId int NOT NULL,
    CONSTRAINT PK_OgrId_StrId_UserId
        PRIMARY KEY(OgrId, StrId, UserId)
)

DECLARE @ogrId int = 99;
DECLARE @strId int = 44;
DECLARE @userId int = 1223;
DECLARE @id int = 14;

DECLARE @querySelect int = 
    (SELECT ProductId FROM dbo.TestData
        WHERE
            OgrId = @ogrId AND 
            StrId = @strId AND 
            UserId = @userId);

IF @querySelect IS NULL
    BEGIN
        INSERT INTO dbo.TestData(OgrId, StrId, UserId, ProductId)
        VALUES (@ogrId , @strId , @userId, @id);
    END
ELSE IF @querySelect <> @id
    BEGIN
        UPDATE dbo.TestData
        SET ProductId= @id
        WHERE 
            OgrId = @ogrId AND 
            StrId = @strId AND 
            UserId = @userId;
    END