#sql-server #oracle #ssis
Вопрос:
У меня есть таблица данных в Oracle, которая содержит следующие столбцы:
Record_ID, Run_ID, PO_Type, PO_NUM, DateTime
При создании заказа на покупку заполняются все столбцы, за исключением Run_ID
:
Record_ID, Run_ID, PO_Type, PO_Num, DateTime --------------------------------------------------- 1374, , NEW_PO , 12345 , 20211117123456 1375, , NEW_PO , 12346 , 20211117123545
В настоящее время эти записи экспортируются из нашей системы через SSIS, где они импортируются в базу данных SQL Server. Именно здесь они будут назначены RUN_ID
, которые будут уникальны для всех выполнений данных, которые были экспортированы (все, что было экспортировано в одно время, будет иметь одно и то же Run_ID
):
RECORDID, SYSTEM, RUN_ID, PO_TYPE, PO_NUM, DATETIME --------------------------------------------------------- 1374, ORDER , 5078 , NEW_PO , 12345 , 20211117123456 1375, ORDER , 5078 , NEW_PO , 12346 , 20211117123545
Затем мне нужно записать это в базу данных Oracle Run_ID
и обновить PO_TYPE
от NEW_PO
до Processed_PO
, чтобы моя база данных Oracle выглядела следующим образом:
Record_ID, Run_ID, PO_Type , PO_Num, DateTime -------------------------------------------------------- 1374, 5078 , Processed_PO , 12345 , 20211117123456 1375, 5078 , Processed_PO , 12346 , 20211117123545
Проблема, с которой я сталкиваюсь, заключается в том, что все это должно происходить в рамках одной и той же службы SSIS, поскольку это единственный доступный мне инструмент, и я не знаю, как начать с этого, поэтому любые советы по этому вопросу будут весьма признательны.
Комментарии:
1. Правильное решение вполне может зависеть от того, как именно генерируется RUN_ID и назначается строкам на стороне MSSQL. У вас также могут возникнуть проблемы со временем, поэтому также важно, как вы выбираете строки на стороне Oracle для экспорта.
2. У меня есть отдельные задачи потока данных, которые 1) Извлекают данные из базы данных Oracle 2) Присваивают отдельный идентификатор Run_ID данным MS_SQL, и я хочу, чтобы 3-я задача потока данных выполняла обновление для Oracle, чтобы не было никаких шансов, что идентификатор Run_ID еще не будет сгенерирован. Идентификатор RUN_ID создается из таблицы SQL. В задаче потока данных 2 SQL обновляет набор SQL_PO Run_ID = RUN_ID_TRACKER.RUN_ID, Затем другая задача SQL обновляет набор RUN_ID_TRACKER RUN_ID = RUN_ID 1
3. Не могли бы вы просто добавить задачу, которая запускает инструкцию update в таблице Oracle, используя нужный вам идентификатор RUN_ID? Сохраните run_id в пользовательской переменной внутри пакета и используйте его для обновления Oracle.
4. @MplsDBA, я пытаюсь найти способ сделать что-то в этом роде, да. Но я также хочу убедиться, что я обновляю только те идентификаторы записей, которые я извлек ( возможно, что другие PO могли быть добавлены в систему во время извлечения, и я не хочу рисковать обновлением одного из них с помощью Run_ID, когда они фактически не были обработаны. ) Поэтому я считаю, что способ проверки того, что обработанные идентификаторы Record_ID являются теми, которые получают правильные идентификаторы Run_ID, является хорошим методом, поэтому следует включить какой-то метод проверки и балансировки.
Ответ №1:
Учитывая вашу полезную дополнительную информацию, теперь я понимаю, что ваша забота в основном связана с тем, чтобы убедиться, что только те строки, которые вы извлекаете, являются теми, которые вы обновляете позже с помощью RUN_ID.
Самый простой способ, который я мог себе представить, — это использовать столбец PO_TYPE и ввести новый статус что-то вроде «PO_Processing». Я не знаю вашей модели среды / данных, так что это может быть или не быть выполнимым — возможно, у вас есть ограничения на то, что вы можете ввести здесь, — но тогда шаги пакета SSIS будут выглядеть примерно так:
- Обновите нужные строки Oracle
update oracle_table set po_type = 'In_Transit_PO' where lt;your criteriagt;
- Выполните извлечение, используя этот статус в качестве критерия выбора
- Загрузите данные в SQL Server
- Сохраните новый идентификатор RUN_ID в пользовательской переменной в пакете
- Используйте переменную user для обновления строк SQL Server
update SQL_PO set Run_ID = (?) where lt;your criteriagt; ('?' maps to your defined package variable)
- Обновите RUN_ID_TRACKER, чтобы увеличить следующий RUN_ID
- Используйте пользовательскую переменную для обновления строк Oracle путем их сопоставления (точный синтаксис может немного отличаться в зависимости от того, какой поставщик настроен для использования вашего пакета).
update oracle_table set PO_Type = 'Processed_PO', RUN_ID='?' where PO_Type = 'In_Transit_PO'
Таким образом, вы разрешаете создавать новые POs на стороне Oracle во время загрузки, но гарантируете, что только извлеченные вами строки являются теми, которые вы обновляете с помощью RUN_ID. Пара дополнительных шагов в пакете, но каждый из них очень прост. Мало того, что в случае ошибок в процессе у вас есть запись о том, какое именно подмножество записей он пытается обработать, что облегчает отладку.
Если подумать, вы могли бы немного сократить шаги, получив значение run_id и поместив его в переменную перед шагом загрузки, тогда у вас уже есть значение, которое нужно включить при вставке строк — нет необходимости во вторичном обновлении таблицы SQL_PO.