2017-02-07 14 views
0

Я программно генерирую и выполняю пакеты SSIS с использованием C# и SQL Server 2012. Сгенерированные пакеты содержат одну задачу потока данных с плоским файловым источником для чтения CSV и назначение OLE DB, подключенное к SQL Server. Между ними находится компонент Row Count с подключенной функцией SSIS Variable.Как получить количество обработанных строк из программно сгенерированного пакета SSIS в вызывающее приложение?

После завершения выполнения пакета, я хочу получить значение из строки Row обратно в мое вызывающее приложение.

Кажется, что просто создает переменную Count & Row в коде следующим образом:

[...] 

// Row count: Create a package variable to store the row count value 
var ssisRowCountVariable = package.Variables.Add("MySsisVar", false, "User", 0); 

// Row count: Create Row component 
IDTSComponentMetaData100 componentRowCount = dataFlowTask.ComponentMetaDataCollection.New(); 
componentRowCount.Name = "RowCount"; 
componentRowCount.ComponentClassID = "DTSTransform.RowCount.4"; 

// Row count: Get row count design-time instance, and initialize component 
CManagedComponentWrapper instanceRowCount = componentRowCount.Instantiate(); 
instanceRowCount.ProvideComponentProperties(); 

// Row count: Set the variable name property 
instanceRowCount.SetComponentProperty("VariableName", "User::MySsisVar"); 

// Hooking up pipeline Paths 
[...] 

// Execute package 
package.Execute() 

, а затем пытается прочитать значение после выполнения пакета:

int Rows = Convert.ToInt32(ssisRowCountVariable.Value); 

не работает.

Как я могу вернуть значение компонента Row Count в вызывающее приложение?

ответ

2

После игры со вторым подходом я обнаружил, что лучший способ сделать это, похоже, состоит в том, чтобы подключить компонент Row Count, как описано в вопросе, и добавить код, чтобы он мог запустить событие, когда его значение получает набор или изменения:

ssisRowCountVariable.RaiseChangeEvent = true; 

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

class MySsisEvents : DefaultEvents 
{ 
    public int Rows { get; private set; } 

    public override void OnVariableValueChanged(DtsContainer DtsContainer, Variable variable, ref bool fireAgain) 
    { 
     this.Rows = Convert.ToInt32(variable.Value); 
    } 
} 

вызов package.Execute() должен быть изменен, чтобы зацепить вверх по обработчик событий следующим образом:

// Execute package 
var mySsisEventHandler = new MySsisEvents(); 
package.Execute(null, null, mySsisEventHandler, null, null); 

Количество обработанных строк теперь доступно как mySsisEventHandler.Rows.

1

К сожалению, вы не можете получить значения времени выполнения переменных пакета из package.Execute(). Однако ваша задача получить # обработанных записей может быть достигнута по-разному одним из следующих способов:

  • Добавить задачу в пакет, который сохраняет значение из переменной обработанных строк в некоторую память. Задача может быть либо после DataFlow, либо в обработчике PostExecute.
    Хранение может представлять собой базу данных SQL или что-то еще, такое как веб-сервис; значение будет сохранено либо с помощью Выполнение SQL-задачи для SQL DB или Задача сценария/веб-службы для веб-службы. Это подход good review.
  • Используйте информационное сообщение DataFlow, соответствующее информационным сообщениям PostExecute. [SSIS.Pipeline] Information: "<your destination name>" wrote N rows. Выполняйте события захвата пакетов, как описано в MSDN, а затем проверьте результаты.

Обратите внимание, что второй подход будет работать только в том случае, если вы запускаете пакет как package.Execute в SSIS без использования каталога SSIS. Если вы сами генерируете пакеты и выполняете их сразу после генерации - все в порядке, вы не создаете и не развертываете проекты SSISDB.

+0

Я пробовал второй подход, но PostExecute - это неправильное событие, так как он не имеет параметра, который дает вам информационное сообщение, которое вы упомянули. Событие OnInformation делает (параметр _description_, но пока событие срабатывает несколько раз, ни одно событие с текстом '' <ваше имя назначения> не записывает N строк. – Blade