#sql #azure-data-factory #sql-merge
#sql #azure-фабрика данных #sql-слияние
Вопрос:
По-видимому, это очень распространенная ошибка, с которой сталкивается большинство людей при работе с операторами слияния SQL. Я тоже сталкивался с этим много раз, и обычно я нахожу дубликаты записей в своем источнике. После устранения проблемы я готов пойти еще раз.
Однако на этот раз для меня все немного по-другому. Я уверен (и проверял много раз), что в моем исходном коде нет повторяющихся строк. Что у меня есть, так это дубликаты идентификаторов, которые составляют уникальные строки (но ни одна строка не совпадает).
Например, см. прилагаемый:
RecId-это уникальный идентификатор для этой конкретной строки. Схема и элемент обслуживания-это 2 разные таблицы, которые были объединены в одну таблицу dbo.Таблица 1.
Рецидив 309 в цепи и рецидив 309 в эксплуатации являются уникальными в каждом из их источников.
Когда я пытаюсь объединить эту существующую таблицу в другую таблицу, я получаю типичную ошибку
Msg 8672, Уровень 16, Состояние 1, Этап Выполнения Процедуры.Пример, Строка 4 [Строка запуска Пакета 0]
Инструкция MERGE пыталась ОБНОВИТЬ или УДАЛИТЬ одну и ту же строку несколько раз. Это происходит, когда целевая строка совпадает с несколькими исходными строками. Инструкция MERGE не может ОБНОВЛЯТЬ/УДАЛЯТЬ одну и ту же строку целевой таблицы несколько раз. Уточните предложение ON, чтобы убедиться, что целевая строка соответствует не более чем одной исходной строке, или используйте предложение GROUP BY для группировки исходных строк.
Может кто-нибудь, пожалуйста, помочь мне. Как мне объединить dbo.Таблица 1 в целевую таблицу без получения ошибки
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROC [Staging].[uspMergeCherwellComConfigurationItem] AS BEGIN MERGE [Cherwell].[ConfigurationItem] AS [Target] USING [Staging].[ConfigurationItem] AS [Source] ON [Source].[RecID] = [Target].[RecID] WHEN MATCHED AND CONVERT(DATETIME, [Source].[LastModifiedDateTime]) lt;gt; [Target].[LastModifiedDateTime] THEN UPDATE SET [Target].[PartitionKey] = [Source].[PartitionKey], [Target].[RecID] = [Source].[RecID], [Target].[ConfigurationItemTypeName] = [Source].[ConfigurationItemTypeName], [Target].[CreatedDateTime] = [Source].[CreatedDateTime], [Target].[Status] = [Source].[Status], [Target].[CIType] = [Source].[CIType], [Target].[FriendlyName] = [Source].[FriendlyName], [Target].[FinancialReference] = [Source].[FinancialReference], [Target].[OrganisationGroup] = [Source].[OrganisationGroup], [Target].[Further_Detail] = [Source].[Further_Detail], [Target].[CICount] = [Source].[CICount], [Target].[unit] = [Source].[unit], [Target].[LastModifiedDateTime] = CONVERT(DATETIME, [Source].[LastModifiedDateTime]) WHEN NOT MATCHED THEN INSERT ([PartitionKey], [RecID], [ConfigurationItemTypeName], [CreatedDateTime], [LastModifiedDateTime], [Status], [CIType], [FriendlyName], [FinancialReference], [OrganisationGroup], [Further_Detail], [CICount], [unit] ) VALUES ([Source].[PartitionKey], [Source].[RecID], [Source].[ConfigurationItemTypeName], [Source].[CreatedDateTime], CONVERT(DATETIME, [Source].[LastModifiedDateTime]), [Source].[Status], [Source].[CIType], [Source].[FriendlyName], [Source].[FinancialReference], [Source].[OrganisationGroup],[Source].[Further_Detail], [Source].[CICount], [Source].[unit]); END;
Комментарии:
1. Вы не указали код , который пытается выполнить
MERGE
, что затрудняет нам понимание того, что происходит. Был бы я прав , предположив, что вы только проверяетеRecID
, но почему-то не включаетеunit
это как частьMERGE
илиJOIN
?2. Спасибо, что указали на это! Теперь я добавил сохраненный сценарий proc в исходное сообщение. и вы правы в своем предположении. Я использую RecId только как часть СЛИЯНИЯ. Я попытался использовать другие уникальные идентификаторы, такие как дружественное имя, как часть СЛИЯНИЯ, но я начал видеть повторяющиеся строки каждый раз, когда выполнял Сохраненный процесс слияния.
3. Разве не странно, что рецидив не уникален в данных? С таким именем можно было бы предположить, что это ПК, но, очевидно, это не так.
4. Что касается проблемы, очевидно, что вы не можете использовать только RecId в качестве уникального ключа, потому что у вас есть совпадения между системами. Если
unit
указывает на систему, это должно стать частью составного ключа, гарантирующего уникальность. Если вы занимаетесь хранилищем данных, наш типичный подход заключается в добавлении измерения SourceSystem и добавлении ссылки на него в этот набор данных. Таким образом, вы можете различать перекрывающиеся строки и легко отслеживать строку до ее исходной системы.5. @gumdrop — Измените это:
ON [Source].[RecID] = [Target].[RecID]
на это:ON [Source].[RecID] = [Target].[RecID] AND [Source].[unit] = [Target].[unit]
. Затем вы должны извлечь устройство изUPDATE SET
детали ниже.
Ответ №1:
Измените это:
MERGE [Cherwell].[ConfigurationItem] AS [Target] USING [Staging].[ConfigurationItem] AS [Source] ON [Source].[RecID] = [Target].[RecID] WHEN MATCHED AND CONVERT(DATETIME, [Source].[LastModifiedDateTime]) lt;gt; [Target].[LastModifiedDateTime] THEN UPDATE SET [Target].[PartitionKey] = [Source].[PartitionKey], [Target].[RecID] = [Source].[RecID], [Target].[ConfigurationItemTypeName] = [Source].[ConfigurationItemTypeName], [Target].[CreatedDateTime] = [Source].[CreatedDateTime], [Target].[Status] = [Source].[Status], [Target].[CIType] = [Source].[CIType], [Target].[FriendlyName] = [Source].[FriendlyName], [Target].[FinancialReference] = [Source].[FinancialReference], [Target].[OrganisationGroup] = [Source].[OrganisationGroup], [Target].[Further_Detail] = [Source].[Further_Detail], [Target].[CICount] = [Source].[CICount], [Target].[unit] = [Source].[unit], [Target].[LastModifiedDateTime] = CONVERT(DATETIME, [Source].[LastModifiedDateTime])
к этому:
MERGE [Cherwell].[ConfigurationItem] AS [Target] USING [Staging].[ConfigurationItem] AS [Source] ON [Source].[RecID] = [Target].[RecID] AND [Target].[unit] = [Source].[unit] WHEN MATCHED AND CONVERT(DATETIME, [Source].[LastModifiedDateTime]) lt;gt; [Target].[LastModifiedDateTime] THEN UPDATE SET [Target].[PartitionKey] = [Source].[PartitionKey], [Target].[RecID] = [Source].[RecID], [Target].[ConfigurationItemTypeName] = [Source].[ConfigurationItemTypeName], [Target].[CreatedDateTime] = [Source].[CreatedDateTime], [Target].[Status] = [Source].[Status], [Target].[CIType] = [Source].[CIType], [Target].[FriendlyName] = [Source].[FriendlyName], [Target].[FinancialReference] = [Source].[FinancialReference], [Target].[OrganisationGroup] = [Source].[OrganisationGroup], [Target].[Further_Detail] = [Source].[Further_Detail], [Target].[CICount] = [Source].[CICount], [Target].[LastModifiedDateTime] = CONVERT(DATETIME, [Source].[LastModifiedDateTime])
Это в основном добавляет [unit]
как часть JOIN
, тем самым обеспечивая уникальность между строками с похожими RecIds
. И то, что это сейчас является частью ключа, мы больше не используем его в UPDATE
заявлении.
Изменения в строке 3: AND [Target].[unit] = [Source].[unit]
Добавление в предложение ON. Изменения в строке 17: Удалена строка из обновления).