#ssis #etl #ssis-projects
Вопрос:
У меня возникла проблема, когда я использовал временную таблицу источника OLE-DB в службах SSIS.
Я создаю временную таблицу в задаче «Выполнить инструкцию T-SQL» и изменяю значение DelayValidation : True и значение RetainSameConnection : True . Но проблема не решена .
Ответ №1:
Фон
Скорее всего, здесь происходит то, что в данный момент таблицы не существует. Временные таблицы бывают двух вариантов: локальные и глобальные.
Локальная временная таблица, использует имя с одним острым/фунтом/хэшем/октоторпом, добавленным к нему, т. е. #TEMP
. Единственный запрос, который может использовать этот экземпляр временной таблицы, — это тот, который ее создает. Вот почему в советах по Интернету говорится, что вам нужно установить RetainSameConnection
значение true, чтобы убедиться, что соединение, создавшее таблицу, повторно используется в потоке данных. В противном случае вы находитесь во власти объединения соединений, и, возможно, одно и то же соединение используется в обоих местах, а может быть, и нет, и, поверьте мне, это неприятная случайность, которую нужно попытаться отладить. Причина DelayValidation
включения потока данных заключается в том, что при запуске пакета механизм проверит, что все данные выглядят так, как ожидалось, прежде чем выполнять какую-либо работу. Поскольку предшествующий шаг-это то, что переводит задачу потока данных в ожидаемое состояние, нам нужно указать исполнению, чтобы оно проверяло задачу только непосредственно перед выполнением. Проверка всегда происходит, это просто вопрос того, когда вы платите цену.
Глобальная временная таблица определяется с добавлением к ней двойного знака sharp/etc, ##TEMP
. Это доступно любому процессу, а не только соединению, которое его создало. Он будет жить до тех пор, пока создающее соединение не исчезнет (или явно не удалит его).
Разрешение
Как только пакет будет разработан (метаданные будут установлены в потоке данных), использование локальной временной таблицы будет работать просто отлично. Однако при его разработке невозможно использовать локальную временную таблицу в качестве источника в потоке данных. Если вы выполните предшествующий шаг, это соединение откроется, создаст временную таблицу, а затем соединение исчезнет, как и временная таблица.
Я бы решил эту проблему следующими шагами
- Скопируйте запрос в задачу «Выполнение SQL» в окно в SSMS и создайте локальную временную таблицу как глобальную временную таблицу, таким образом
##TEMP
. - Создайте переменную SSIS с именем SourceQuery типа String со значением
SELECT * FROM ##TEMP;
- Измените «Режим доступа к данным» из источника OLE DB с «Команда SQL» на «Команда SQL из переменной» и используйте переменную
User::SourceQuery
- Завершите проектирование потока данных
- Сохраните пакет, чтобы убедиться, что метаданные сохраняются
- Измените запрос в нашей переменной со ссылки ##TEMP на #TEMP
- Сохраните еще раз.
- Удалите временную таблицу ##или закройте соединение
- Запустите пакет, чтобы убедиться, что все работает так, как я ожидаю.
Шаги 2, 3 и 6 выше позволяют вам подражать фокуснику, вытаскивающему скатерть из-под всех тарелок.
Если вы вручную отредактируете запрос в самом потоке данных с ##TEMP на #TEMP, начнется проверка, и, поскольку таблица #TEMP недоступна, она сообщит о VS_NEEDSNEWMETADATA и, вероятно, не позволит вам сохранить пакет. Использование переменной в качестве источника запроса обеспечивает уровень косвенности, который позволяет нам обойти этап «проверка при изменении»/повторная инициализация метаданных.
Комментарии:
1. Большое вам спасибо, ценю это. Я создал временную таблицу##, сделал сопоставление,затем удалил временную таблицу ##и запустил процесс.
2. Есть ли какой-либо вред в использовании глобальной временной таблицы? Я спрашиваю, потому что, независимо от глобального или локального, вам все равно нужно установить в диспетчере соединений значение сохранить то же соединение, что и значение True.
3. @переменная Риск глобальной временной таблицы заключается в том, что внешние процессы могут взаимодействовать с вашими данными. Еще одним риском может быть то, что вы используете кодирование копирования/вставки в своей среде, кто-то также может создать ##TEMP, и ваш процесс попытается его создать и выдаст ошибки. Так что выбирайте хорошие имена. Я уверен, что есть и другие соображения по использованию глобальных и локальных временных таблиц, но они выходят за рамки моей проблемы