У меня есть пакет служб SSIS, который начинается с задачи сценария, которая инициализирует пустой объект DataTable и присваивает его переменной пользователя. Я добавляю несколько примеров строк, так как я все еще занимаюсь разработкой. Переменная называется: FlatFileBadRowDataTracker
в SSIS.
public void Main()
{
// TODO: Add your code here
string SSISRunStartTimeStamp = DateTime.Now.ToString("yyyyMMddHHmmss");
Dts.Variables["User::SSISRunStartTimeStamp"].Value = SSISRunStartTimeStamp;
Dts.Variables["User::FlatFileBadRowDataTracker"].Value = BuildSampleDataTable();
Dts.TaskResult = (int)ScriptResults.Success;
}
private DataTable BuildSampleDataTable()
{
DataTable dt = new DataTable();
// ErrorColumn
DataColumn errorColumn = new DataColumn("ErrorColumn");
errorColumn.DataType = System.Type.GetType("System.String");
errorColumn.DefaultValue = string.Empty;
dt.Columns.Add(errorColumn);
// ErrorDescription
DataColumn errorDescription = new DataColumn("ErrorDescription");
errorColumn.DataType = System.Type.GetType("System.String");
errorColumn.DefaultValue = string.Empty;
dt.Columns.Add(errorDescription);
// FileName
DataColumn fileName = new DataColumn("FileName");
errorColumn.DataType = System.Type.GetType("System.String");
errorColumn.DefaultValue = string.Empty;
dt.Columns.Add(fileName);
// RawData
DataColumn rawData = new DataColumn("RawData");
errorColumn.DataType = System.Type.GetType("System.String");
errorColumn.DefaultValue = string.Empty;
dt.Columns.Add(rawData);
// ErrorDescription
DataColumn dataFlowComponent = new DataColumn("DataFlowComponent");
errorColumn.DataType = System.Type.GetType("System.String");
errorColumn.DefaultValue = string.Empty;
dt.Columns.Add(dataFlowComponent);
// Populate with some sample data.
DataRow row;
for (int i = 1; i < 5; i++)
{
row = dt.NewRow();
row["ErrorColumn"] = "ErrorColumn" + i;
row["ErrorDescription"] = "ErrorDescription" + i;
row["FileName"] = "FileName" + i;
row["RawData"] = "RawData" + i;
row["DataFlowComponent"] = "SSIS_DataFlowTask_" + i;
dt.Rows.Add(row);
}
return dt;
}
#region ScriptResults declaration
/// <summary>
/// This enum provides a convenient shorthand within the scope of this class for setting the
/// result of the script.
///
/// This code was generated automatically.
/// </summary>
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
Затем у меня есть задача потока данных, которая читает текстовый файл (csv через компонент источника плоских файлов) и имеет компонент Script (как преобразование) который определяет, являются ли строки хорошими или плохими. Хорошие строки отправляются на выход «GoodRow», а плохие строки отправляются на «BadRows» из компонента Script. Обычно файл содержит в основном хорошие строки, но некоторые из них имеют ошибки данных (например, в столбце электронной почты есть что-то, что не похоже на адрес электронной почты), и в этом случае компонент должен отправить это в вывод BadRows. Моя цель - записать данные, связанные с ошибками (например, имя столбца с ошибкой данных и некоторое описание вместе с ним) в ту же таблицу данных, которую я создал в задаче сценария ранее.
Я добавил эту переменную в ReadWriteVariables в Свойствах экрана редактора компонентов скрипта. Я использую его в PreExecute()
, чтобы получить схему DataTable и присвоить ей dt
, которая является локальной переменной, которую я объявил в начале класса.
public override void PreExecute()
{
base.PreExecute();
dt = (DataTable)Variables.FlatFileBadRowDataTracker;
}
Затем Я пытаюсь добавить данные в dt
, как и когда я нахожу связанные с данными ошибки в методе Input0_ProcessInputRow(Input0Buffer Row)
. После этого в PostExecute()
я пытаюсь присвоить dt
обратно пользовательской переменной.
public override void PostExecute()
{
base.PostExecute();
Variables.FlatFileBadRowDataTracker = dt;
}
Однако, когда я запускаю пакет, я получаю эту ошибку (показанную ниже), которая говорит мне, что я не могу использовать переменную в методе PreExecute (). Кажется, я могу использовать его только в методе PostExecute (). Мне нужны существующие данные + схема таблицы данных, в противном случае мне придется пересоздать схему, и я потеряю данные (на данный момент это только тестовые данные, как показано в коде).
Можно ли как-нибудь получить схему + данные объекта DataTable в моем компоненте сценария? Компонент Script также не позволяет мне добавлять переменные в ReadOnlyVariables
и ReadWriteVariables
. Кажется, я могу добавить его только к одному из них.