Я бы отделил процесс импорта от любых триггеров. Триггер полезен, если вы хотите, чтобы строки постоянно добавлялись в таблицу импорта из постоянно работающего внешнего источника. Это не похоже на вашу ситуацию, так как вы будете импортировать весь файл одновременно. Триггеры, как правило, скрывают код и в некоторых ситуациях могут быть трудны для работы.
Как часто вы импортируете эти файлы?
У меня будет процесс импорта, который будет в основном автономным. Он может использовать хранимые процедуры или таблицы в базе данных, но я бы не использовал триггеры. Простой подход будет что-то вроде ниже. Я добавил столбец в Legacy_Invoices
(также переименованный во что-то более наглядное), чтобы вы могли отслеживать, когда элементы были импортированы и откуда. Вы можете расширить это, чтобы отслеживать больше информации при необходимости.
Кроме того, я не вижу, как вы отслеживаете номера счетов в вашем коде. Я предположил столбец IDENTITY в Legacy_Invoices
. Этого почти наверняка недостаточно, так как я предполагаю, что вы также создаете счета в своей собственной системе (за пределами прежней системы). Однако, не зная схемы нумерации счетов, невозможно найти решение там.
BEGIN TRAN
DECLARE
@now DATETIME = GETDATE()
UPDATE Legacy_Invoices
SET
import_datetime = @now
WHERE
import_status = 'Awaiting Import'
INSERT INTO dbo.Invoices (invoice_no, cust_no)
SELECT DISTINCT invoice_no, cust_no
FROM
Legacy_Invoices
WHERE
import_datetime = @now
UPDATE Legacy_Invoices
SET
import_status = 'Invoice Imported'
WHERE
import_datetime = @now
INSERT INTO dbo.Invoice_Lines (invoice_no, item_no, item_qty, item_prc)
SELECT
invoice_no,
item_no_1,
item_qty_1,
item_prc_1
FROM
Legacy_Invoices LI
WHERE
import_datetime = @now AND
import_status = 'Invoice Imported' AND
item_no_1 IS NOT NULL
UPDATE Legacy_Invoices
SET
import_status = 'Item 1 Imported'
WHERE
import_datetime = @now AND
import_status = 'Invoice Imported'
<Repeat for item_no_2 through 7>
COMMIT TRAN
Вот большая оговорка. Хотя курсоры обычно нежелательны в SQL, и вы хотите использовать обработку на основе множеств по сравнению с обработкой RBAR (строка за агонизирующей строкой), импорт данных часто является исключением.
Проблема с вышесказанным заключается в том, что, если одна строка завершается с ошибкой, весь шаг импорта завершается неудачно. Кроме того, очень сложно запустить один объект (счет-фактура плюс позиции) с помощью бизнес-логики, когда вы импортируете их в большом количестве. Это то место, где SSIS действительно сияет. Это очень быстро (при условии, что вы настроили его правильно), даже при импорте одного объекта за раз. Затем вы можете поместить в него все виды обработки ошибок, чтобы обеспечить бесперебойную работу импорта. Одна строка импорта имеет ошибочный номер счета? Нет проблем, отметьте это как ошибку и продолжайте. В строке заполнена позиция № 2, но нет позиции № 1 или есть цена без количества? Нет проблем, отметьте ошибку и продолжайте.
Для одного импорта я мог бы придерживаться приведенного выше кода (конечно, добавляя соответствующую обработку ошибок), но для повторяющегося процесса я почти наверняка использовал бы SSIS. Вы можете импортировать миллионы строк в считанные секунды или минуты, даже с индивидуальной обработкой ошибок для каждого бизнес-объекта.
Если у вас есть какие-либо проблемы с запуском SSIS (во всей сети и по MSDN есть учебные пособия в Microsoft), опубликуйте здесь любые проблемы, и вы должны получить быстрые ответы.