SSIS 2012 - переменная пуста при втором выполнении скрипта - PullRequest
2 голосов
/ 22 марта 2019

У меня есть преобразование компонента скрипта в поток данных. В этом компоненте скрипта я читаю таблицу из переменной объекта. Первая запись, которая проходит через скрипт, работает нормально. Переменная читается правильно и отлично загружается в объект списка.

Следующая запись передается в скрипт, что-то идет не так.

Глядя на переменную, она сообщает о количестве записей 44, когда она пытается загрузить в мой список, я получаю rowcount = 0

Ниже приведен скрипт, который загружает список

    List<PublicHoliday> PublicHolidays = new List<PublicHoliday>();


    OleDbDataAdapter A = new OleDbDataAdapter();
    DataTable dt = new DataTable();
    A.Fill(dt, Variables.LISTPublicHolidays);

    foreach (DataRow row in dt.Rows)
    {
        object[] array = row.ItemArray;
        var Public = new PublicHoliday()
        {
            DateKey = int.Parse(array[0].ToString()),
            FullDateAlternateKey = DateTime.Parse(array[1].ToString())
        };
        PublicHolidays.Add(Public);
    }

Я что-то упустил? Кто-нибудь сталкивался с этой проблемой раньше?

1 Ответ

2 голосов
/ 22 марта 2019

Попытка выяснить проблему

Из следующей документации по методу OleDbDataAdapter.Fill (DataTable, Object) :

ВНИМАНИЕ
При использовании объектов ADO Recordset или Record в сочетании с приложениями .NET Framework всегда вызывайте Close, когда вы закончите. Это обеспечивает своевременное освобождение базового соединения с источником данных, а также предотвращает возможные нарушения доступа из-за того, что неуправляемые объекты ADO возвращаются при сборке мусора, когда существующие ссылки еще существуют.

Также относится к Заполнение набора данных набором записей ADO или записью - документация :

Обратите внимание, что перегрузка OleDbDataAdapter.Fill, которая принимает объект DataSet и объект ADO, неявно вызывает Close для объекта ADO, когда операция Fill завершена. Вам необходимо явно закрыть объект ADO Recordset или Record после вызова перегрузки OleDbDataAdapter.Fill, которая принимает DataTable.

Это означает, что при вызове метода Fill через RecordSet вы должны закрыть его перед повторным использованием, иначе строки не будут возвращены.


Возможные обходные пути

Я не знаю, как на самом деле закрыть переменную Recordset from Object, но я постараюсь предоставить некоторые возможные обходные пути:

(1) Сохранение в DataTable

В приведенной ниже ссылке упоминается следующий обходной путь:

  1. Как только мой Recordset @[User::FilePath] будет заполнен, я использую задачу Script и заполняю ее в DataSet ds, используя OledbDataAdapter и DataTable.

  2. Затем, в той же задаче скрипта, я присвоил значение ds новому переменная типа объекта @[User::FilePathDataTable].

При этом тип данных FilePathDataTable становится System.Data.DataTable.

Этот набор данных можно легко использовать любое количество раз внутри Петля For-Each.

Я не использую DataAdapter.Fill() метод внутри цикла ForEach ssis сейчас. Я просто присваиваю значение @[User::FilePathDataTable] новому набор данных и использовать его для итераций.

Ссылка

(2) Использование источника записей

Вместо использования компонента Script для генерации строк из переменной Object попробуйте сделать это с помощью RecordSet Source.

(3) Приведение переменной в качестве набора записей

Я не проверял этот подход, и я не уверен, будет ли он работать с объектной переменной

Требуется ссылка на объекты данных Microsoft ActiveX.

List<PublicHoliday> PublicHolidays = new List<PublicHoliday>();

var rs = ((ADODB.Recordset)Variables.LISTPublicHolidays);
OleDbDataAdapter A = new OleDbDataAdapter();
DataTable dt = new DataTable();
A.Fill(dt, rs);

foreach (DataRow row in dt.Rows)
{
    object[] array = row.ItemArray;
    var Public = new PublicHoliday()
    {
        DateKey = int.Parse(array[0].ToString()),
        FullDateAlternateKey = DateTime.Parse(array[1].ToString())
    };
    PublicHolidays.Add(Public);
}
rs.Close();

Обновление 1

на основе приведенных ниже комментариев попробуйте удалить метод rs.Close(); из первого сценария и во втором сценарии перед выполнением метода Fill, используйте метод rs.MoverFirst(), чтобы иметь возможность извлекать информацию из набора записей.

Третий подход удален по следующей ссылке:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...