Возможный моделировать функциональность MySQL НА ДУБЛИРУЮЩЕМСЯ КЛЮЧЕВОМ ОБНОВЛЕНИИ с SQL Server

Я использую SQL Server 2008 и хотел бы смочь использовать в своих интересах что-то как mySQL's НА DUPLICATE KEY UPDATE пункт для INSERT операторы

Текущий унаследованный код делает удаление и последующую вставку, которая сталкивается с проблемами параллелизма с, делают дубликат ключа, вставляет от отдельных потоков:

Вот ошибка, которую я вижу в своей продуктивной среде:

Violation of PRIMARY KEY constraint 'PK_Audience'. Cannot insert duplicate key in object 'dbo.Audience'.

(sp_ContentUpdate)

Первичный ключ:

AudienceId, VersionId

Оскорбление SQL:

DELETE  FROM  dbo.Audience
WHERE   VersionId = @VersionId

IF  @AudienceXml IS NOT NULL
    BEGIN
    INSERT INTO dbo.Audience (
        VersionId,
        AudienceId,
        CreatedDate,
        CreatedByPersonId,
        )
    SELECT  @VersionId,
            AudienceId,
            GETUTCDATE(),
            @PersonId
                FROM    dbo.Audience
    JOIN    @AudienceXml.nodes('/Audiences/Audience') node(c)
    ON      Audience.AudienceName = c.value('@Name', 'nvarchar(50)')
    END

Обертывание этого TSQL в транзакции, кажется, или удаляет проблему параллелизма или маскирует проблему путем изменения синхронизаций. Однако я не думаю, переносясь в транзакции, на самом деле решил параллелизм.

Возможно, я иду об этой несправедливости. Ваши предложения ценятся.

9
задан OMG Ponies 26 July 2010 в 22:55
поделиться

2 ответа

Что ж, Билл победил всех нас, но вот пример того, как это может выглядеть:

Merge dbo.Audience As target
Using   (
        Select @VersionId As VersionId, AudienceId, GetUtcDate() As CreatedDate, @PersonId As CreatedByPersonId
        From dbo.Audience
            Join @AudienceXml.nodes('/Audiences/Audience') node(c)
                On Audience.AudienceName = c.value('@Name', 'nvarchar(50)')
        )
When Matched Then
    Update 
    Set VersoinId = target.VersionId, Audience = target.AudienceId
        , CreatedDate = target.CreatedDate
        , CreatedByPersionId = target.CreatedByPersonId
When Not Matched Then
    Insert dbo.Audience(VersionId, AudienceId, CreatedDate, CreatedByPersonId)
10
ответ дан 4 December 2019 в 11:39
поделиться

Вам следует прочитать о том, как использовать оператор MERGE в Microsoft SQL Server 2008. На самом деле это ANSI/ISO SQL способ обработки данной ситуации (в MySQL ON DUPLICATE KEY является собственным MySQLism).

См. документацию по оператору MERGE в MSDN.

8
ответ дан 4 December 2019 в 11:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: