Переменная только для чтения SSIS изменяется

У меня есть пакет, внутри которого у меня есть два компонента: первый — это SQL-задача для выполнения и получения результирующего набора ADO, второй — скриптовая задача, я дважды конвертирую результирующий набор в System.Data.DataTable, что-то вроде этого:

 System.Data.DataTable t1= new System.Data.DataTable();
 OleDbDataAdapter adp = new OleDbDataAdapter();
 adp.Fill(t1, Dts.Variables["ResultSet"].Value);

 System.Data.DataTable t2= new System.Data.DataTable();
 OleDbDataAdapter adp2 = new OleDbDataAdapter();
 adp2.Fill(t2, Dts.Variables["ResultSet"].Value);

В результате t1 заполнен правильно, а t2 остается пустым; более того, я явно установил [User::ResultSet] как переменную только для чтения, кажется, что переменная просто опустела, даже если я добавлю еще одну задачу сценария позже и сделаю то же самое снова, заполненные DataTable все еще пусты.

Есть много способов обойти мой случай, поэтому я не ожидаю решения здесь. Но я хочу прояснить эти вещи: есть ли у OleDbDataAdapter.Fill побочные эффекты для исходных наборов данных, и как моя переменная только для чтения изменила свое значение?


person a4194304    schedule 25.01.2018    source источник


Ответы (2)


Я не думаю, что это изменяет значение переменной набора записей только для чтения, проблема в том, что при использовании метода Adapter.Fill для заполнения таблицы данных набором записей набор записей все еще открыт, вы должны явно закрыть его, чтобы иметь возможность используйте его снова с другими адаптерами. (Когда вы пытаетесь прочитать из него снова, он заканчивает предоставление строк, поэтому вы пытаетесь прочитать с конца)

Из следующих статей Microsoft:

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

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

Я действительно не могу найти, как закрыть набор записей SSIS после использования метода Fill, но я нашел ссылку на аналогичную проблему с обходным путем:

person Hadi    schedule 25.01.2018

Fill использует указатель, чтобы узнать, откуда в исходном наборе данных выполняется чтение. После первого заполнения вы находитесь в конце набора переменных данных. Сначала присвойте переменную DTS переменной скрипта:

var d = Dts.Variables["ResultSet"].Value.ToList();

должен позволить вам использовать его несколько раз. См. перемотку курсора DataReader‌.

person Randy Slavey    schedule 25.01.2018