#c# #ssis
#c# #ssis
Вопрос:
Я разрабатываю пользовательский компонент потока данных. Одно из определяемых мной пользовательских свойств содержит строку, содержащую информацию о количестве выходных столбцов, если быть точным, она содержит имена столбцов (может быть 4, может быть 5, но также может быть и 50).
Следовательно, количество выходных столбцов является переменным. Я не могу понять, как (или даже если это возможно) создать компонент с количеством выходных столбцов, которое варьируется в зависимости от входных данных.
У кого-нибудь есть представление о том, как это сделать? Спасибо
Обновить
ОК. Итак, во время разработки я просматриваю свои пользовательские свойства и создаю необходимые столбцы. Каким методом я должен это сделать?
Я попробовал это в ProvideComponentProperties:
this.fields_ = this.ComponentMetaData.CustomPropertyCollection["Fields"].Value.ToString().Split(new Char[] { ',' });
foreach (string _field in fields_)
{
IDTSOutputColumn100 _outputCol = ComponentMetaData.OutputCollection[0].OutputColumnCollection.New();
_outputCol.Name = _field;
_outputCol.SetDataTypeProperties(DataType.DT_STR, 20, 0, 0, 1252);
}
По сути, fields_ разбивает строку, которая выглядит следующим образом:
PRVT_PLACE,OPT_IMPLIED_VOLATILITY_MID,OPT_IMPLIED_VOLATILITY_YEST
И для каждого поля я хочу создать выходной столбец.
Затем я удаляю свой компонент и устанавливаю свойство fields_, но получаю следующее сообщение:
The name for "output column" "(93)" is blank and names cannot contain blanks.
Создается только один столбец с пустым именем вместо 4 в примере выше…
Что я делаю не так?
Ответ №1:
SSIS требует, чтобы метаданные не изменялись во время выполнения. Это означает, что вы можете играть с метаданными сколько угодно во время разработки, но после выполнения пакета: источник, назначение (внешние метаданные: db, file, …) и метаданные конвейера не могут быть изменены. Это механизм безопасности, позволяющий убедиться, что пакет выполнит работу должным образом.
Конечно, есть изменения в метаданных, которые приводят только к предупреждению. Например, адресат oledb заметит изменение типа данных столбца с DT_I2 на DT_I4 (smallint -> int в SQL Server), но это будет работать. Некоторые другие компоненты, такие как SQL Server destination, не допускают никаких изменений в метаданных.
Резюме: можно создать пользовательский компонент, который изменит количество выходных столбцов во время разработки, но невозможно изменить количество столбцов во время выполнения или изменить типы столбцов.
Комментарии:
1. хорошо, я отредактировал свой вопрос, чтобы показать, что я безуспешно пытаюсь во время разработки atm. Спасибо за вашу помощь
Ответ №2:
Я, наконец, нашел решение. Возможно, это не совсем то, что нужно сделать, но это соответствует моим потребностям.
Я переопределил метод OnOutputPathAttached. В этом методе я просматриваю свое свойство fields_ и добавляю столбцы на основе их количества.
ComponentMetaData.OutputCollection[0].OutputColumnCollection.RemoveAll();
string[] fields = this.ComponentMetaData.CustomPropertyCollection["Fields"].Value.ToString().Split(new Char[] { ',' });
foreach (string _field in fields)
{
IDTSOutputColumn100 _outputCol = ComponentMetaData.OutputCollection[0].OutputColumnCollection.New();
_outputCol.Name = _field;
_outputCol.SetDataTypeProperties(DataType.DT_STR, 20, 0, 0, 1252);
}
base.OnOutputPathAttached(outputID);
Ответ №3:
Конечно, вы должны сделать это, переопределив ReinitializeMetaData(). Вы бы сделали это только на outputpathattached, если бы поддерживали разное количество выходных столбцов (потенциально с разными выходными столбцами в каждом).
Я думаю.
Смотрите http://technet.microsoft.com/en-us/library/ms135954.aspx