Как создать первичный ключ на квазиуникальных ключах данных? - PullRequest
2 голосов
/ 04 августа 2011

У меня есть ночной процесс SSIS, который экспортирует TON данных из системы базы данных AS400.Из-за ошибок в программном обеспечении AS400 DB, случайные дубликаты ключей вставляются в таблицы данных.Каждый раз, когда новый дубликат добавляется в таблицу AS400, это убивает мой ночной процесс экспорта.Эта проблема перешла из неприятности в проблему.

Мне нужно иметь возможность вставлять только уникальные данные.Если есть дубликаты, выберите первую встреченную строку из дубликатов.Есть ли доступный синтаксис SQL, который может помочь мне сделать это?Мне известно о предложении DISTINCT ROW , но в моем случае это не сработает, поскольку для большинства ошибочных записей полнота данных не является уникальной, за исключением полей, которые составляют PK.

В моем случае более важно, чтобы мои первичные ключи оставались уникальными в моем кэше БД SQL Server, а не имели полный снимок данных.Есть ли что-то, что я могу сделать, чтобы это ограничение на экспорт в службах SSIS / SQL Server не прервало процесс?

РЕДАКТИРОВАТЬ

Позвольте мне дополнительно уточнить мой запрос.Мне нужно убедиться, что данные в моих экспортированных таблицах SQL Server содержат те же ключи, что и таблицы данных AS400.Другими словами, создание уникального идентификатора числа строк не будет работать, равно как и вставка всех данных без первичного ключа.

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

Этот оператор SELECT, вероятно, должен происходить из оператора SELECT в моем проекте SSIS, который подключается к мэйнфрейму черезсоединение ODBC.

Я подозреваю, что не может быть "простого" решения моей проблемы.Однако я надеюсь, что ошибаюсь.

Ответы [ 4 ]

2 голосов
/ 04 августа 2011

Поскольку вы используете SSIS, вы должны использовать OLE DB Source для извлечения данных из AS400, и вы будете использовать OLE DB Destination для вставки данных в SQL Server.

Давайте предположим, что у вас нет никаких преобразований

Data Flow Task

Добавьте Sort transformation после источника OLE DB. В Преобразовании Сортировки есть опция флажка внизу, чтобы удалить дублирующиеся строки на основе заданного набора значений столбцов. Проверьте все поля, но не выбирайте первичный ключ от AS400. Это исключит повторяющиеся строки, но вставит данные, которые вам все еще нужны.

Sort

Надеюсь, это то, что вы ищете.

1 голос
/ 04 августа 2011

Есть несколько вариантов.

Если вы используете IGNORE_DUP_KEY (опция http://www.sqlservernation.com/home/creating-indexes-with-ignore_dup_key.html) в первичном ключе, SQL выдаст предупреждение, и только дублирующиеся записи завершатся с ошибкой.

Вы также можете группировать / сворачивать свои данные, но это может быть очень дорого. Под этим я подразумеваю:

SELECT Id, MAX(value1), MAX(value2), MAX(value3) etc

Другой вариант - добавить столбец идентификаторов (и кластеризовать его для более эффективного объединения позже) в промежуточную таблицу, а затем создать отображение во временной таблице. Таблица сопоставления будет:

CREATE TABLE #mapping 
( 
    RowID INT PRIMARY KEY CLUSTERED,
    PKIN INT
)

INSERT INTO #mapping
SELECT PKID, MIN(rowid) FROM staging_table  
GROUP BY PKID

INSERT INTO presentation_table
SELECT S.* 
FROM Staging_table S 
    INNER JOIN #mapping M 
        ON S.RowID = M.RowID 
1 голос
/ 04 августа 2011

В SQL Server 2005 и выше:

SELECT  *
FROM    (
        SELECT  *,
                ROW_NUMBER() OVER (PARTITION BY almost_unique_field ORDER BY id) rn
        FROM    import_table
        ) q
WHERE   rn = 1
0 голосов
/ 04 августа 2011

Если я вас правильно понял, у вас есть дубликаты PK, которые имеют другие данные в других полях.

Сначала поместите данные из другой базы данных в промежуточную таблицу.Мне легче исследовать проблемы с импортом (особенно крупными), если я это сделаю.На самом деле я использую две промежуточные таблицы (и для этого случая я настоятельно рекомендую это), одну с необработанными данными, а другую только с данными, которые я намерен импортировать в мою систему.

Теперь вы можете использовать и выполнить задачу SQL, чтобы получить одну из записей для каждого ключа (см. @Quassnoi, чтобы узнать, как это сделать, вам может понадобиться настроить его запрос для вашей ситуации).Лично я помещаю идентификационные данные в свою промежуточную таблицу, чтобы определить, какое первое или последнее появление дублированных данных.Затем поместите запись, которую вы выбрали для каждого ключа, во второй промежуточный стол.Если вы используете таблицу исключений, скопируйте в нее записи, которые вы не перемещаете, и не забудьте код причины для исключения (например, «Дублированный ключ»).

Теперь, когда у вас есть только одна записьдля каждого ключа в промежуточной таблице ваша следующая задача - решить, что делать с другими данными, которые не являются уникальными.Если для одного и того же клиента есть два разных рабочих адреса, какой вы выбрали?Это вопрос определения бизнес-правил, а не строго SSIS или SQL-кода.Вы должны определить бизнес-правила для того, как вы выбрали данные, когда данные должны быть объединены между двумя записями (то, что вы делаете, является эквивалентом процесса дедупликации).Если вам повезет, есть поле даты или другой способ определить, какие данные являются самыми новыми или самыми старыми, и именно эти данные они хотят, чтобы вы использовали.В этом случае, как только вы выбрали только одну запись, вы выполняете начальное преобразование.

Более чем вероятно, хотя вам могут понадобиться разные правила для каждого другого поля, чтобы выбрать правильное.В этом случае вы записываете преобразования SSIS в поток данных или задачи Exec SQl, чтобы выбрать правильные данные и обновить промежуточную таблицу.

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

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