Пакет SSIS не хочет получать метаданные временной таблицы

У меня есть пакет SSIS, который содержит несколько потоков.

Каждый поток отвечает за создание «промежуточной» таблицы, которая заполняется после создания. Эти таблицы являются глобальными временными таблицами.

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

Ошибка, которая продолжает выскакивать:

Обновление - Вставить поток данных: Ошибка: код ошибки SSIS DTS_E_OLEDBERROR. Произошла ошибка OLE DB. Код ошибки: 0x80004005. Доступна запись OLE DB. Источник: «Microsoft SQL Server Native Client 11.0» Hresult: 0x80004005 Описание: «Неизвестная ошибка». Доступна запись OLE DB. Источник: «Microsoft SQL Server Native Client 11.0» Hresult: 0x80004005 Описание: «Метаданные не могут быть определены, потому что инструкция 'select * from' ## TmpMcsConfigurationDeviceHistory86B34BFD041A430E84CCACE78DA336A1 '' использует временную таблицу.».

Выражение создания:

"CREATE TABLE " + @[User::TmpMcsConfigurationDeviceHistory]  + " ([RecId] [bigint] NULL,[DataAreaID] [nvarchar](4) COLLATE database_default NULL,[Asset] [bigint] NULL,[Code] [nvarchar](255) COLLATE database_default NULL,[Configuration] [bigint],[StartdateTime] [datetime] NULL,[EndDateTime] [datetime] NULL)

"

Анализируемое выражение (= оцененное):

CREATE TABLE ##TmpMcsConfigurationDeviceHistory764E56F088DC475C9CC747CC82B9E388 ([RecId] [bigint] NULL,[DataAreaID] [nvarchar](4) COLLATE database_default NULL,[Asset] [bigint] NULL,[Code] [nvarchar](255) COLLATE database_default NULL,[Configuration] [bigint],[StartdateTime] [datetime] NULL,[EndDateTime] [datetime] NULL)

person Mortana    schedule 20.08.2013    source источник


Ответы (6)


Использование WITH RESULT SETS для явного определения метаданных позволит SSIS пропустить шаг sp_describe_first_result_set и использовать метаданные что вы определяете. Положительным моментом является то, что вы можете использовать это, чтобы заставить SSIS выполнять SQL, содержащий временную таблицу (для меня эта производительность очень помогла); Обратной стороной является то, что вам придется вручную поддерживать и обновлять это, если что-то изменится.

Пример запроса (хранимая процедура :)

    EXEC ('dbo.MyStoredProcedure')
    WITH RESULT SETS
      (
        (
            MyIntegerColumn INT NOT NULL,
            MyTextColumn VARCHAR(50) NULL,
            MyOtherColumn BIT NULL
        )
      )

Пример запроса (простой SQL :)

EXEC ('
    CREATE TABLE #a 
      (
        MyIntegerColumn INT NOT NULL,
        MyTextColumn VARCHAR(50) NULL,
        MyOtherColumn BIT NULL
      ) 
    INSERT INTO #a 
      (
        MyIntegerColumn,
        MyTextColumn,
        MyOtherColumn
      )
    SELECT 
        1 AS MyIntegerColumn,
        ''x'' AS MyTextColumn,
        0 AS MyOtherColumn

    SELECT MyIntegerColumn, MyTextColumn, MyOtherColumn
    FROM #a')

WITH RESULT SETS
    (
        (
            MyIntegerColumn INT NOT NULL
           ,MyTextColumn VARCHAR(50) NULL
           ,MyOtherColumn BIT NULL
        )
    )
person AHiggins    schedule 04.02.2015
comment
Этот ответ сработал для меня. Приведенный выше ответ с командами FMTONLY закончился отправкой 0 строк на вывод во время фактического ETL. - person efesar; 04.05.2015
comment
Спасибо - это было действительно полезное решение, на которое я только что наткнулся. - person MISNole; 08.04.2016
comment
Работает! Я использую Visual Studio 2017. Я работаю с небольшим, зрелым набором хранимых процедур, поэтому этот метод отлично подходит для процессов, которые не нужно часто менять. Спасибо, Хиггинс. - person midoriha_senpai; 04.12.2018
comment
Фантастическое решение, оно сработало для меня, когда мне нужно было использовать несколько таблиц #TempTables для оптимизации производительности запросов. Я могу спать спокойно этой ночью, так что спасибо, что поделились этим золотым самородком AHiggins & MrEdmundo - person Goku; 13.05.2020

Другой вариант (своего рода взлом, но он работает и не требует от вас изменения использования глобальных временных таблиц) - использовать команду SET FMTONLY ON перед вашим фактическим запросом, чтобы отправить поддельный «Первый набор результатов» на SSIS с правильной структурой столбцов. Итак, вы можете сделать что-то вроде

SET FMTONLY ON
select 0 as a, 1 as b, 'test' as C, GETDATE() as D
SET FMTONLY OFF

select a, b, c, d from ##TempTable

Когда SSIS запускает sp_describe_first_result_set, он возвращает метаданные и имена столбцов вашей команды FMTONLY и не будет жаловаться на то, что не может определить метаданные вашей временной таблицы, потому что он даже не будет пытаться.

person Kyle Hale    schedule 21.08.2013
comment
Спасибо, я был в месте, где был триггер, использующий временную таблицу, и я не мог коснуться триггера (не спрашивайте) ... Это было то, что мне нужно - person Rikon; 04.09.2014
comment
Спустя полтора года, но все еще полезно. Спасибо, Кайл. - person Hannover Fist; 03.04.2015
comment
Это сработало. Мне пришлось сделать еще несколько шагов, чтобы все заработало. В моем запросе было 40+ полей, некоторые из них bigint, некоторые десятичные (19,4). В поддельном выборе внутри FMTONLY мне приходилось много раз писать что-то вроде CAST (NULL AS DECIMAL (19,4)) как MyDecimalField. - person Johannes Wentu; 28.01.2016
comment
К вашему сведению: SET FMTONLY устарел с SQL Server 2012. msdn.microsoft.com/en-us/library/ms143729 (v = sql.110) .aspx - person Guoliang; 28.05.2016

Если вы работаете над SSIS 2012, то он использует системную хранимую процедуру sp_describe_first_result_set для получения метаданных таблиц и не поддерживает временные таблицы. Но вы можете выбрать другие параметры, такие как переменные таблицы и CTE, которые будут работать нормально. https://connect.microsoft.com/SQLServer/feedback/details/629077/denali-engine-metadata-discovery-shuns-temp-tables.

person Sonam    schedule 20.08.2013
comment
Я использую переменные таблицы в своих потоках данных (это мой первый день использования SSIS, поэтому я надеюсь, что я прав), они просто содержат DDL для создания временной таблицы, как и все другие потоки данных (хотя он работает в других потоках данных ). - person Mortana; 21.08.2013
comment
Как я вижу в описании вашей ошибки, запрос выбора выполняется для временной таблицы, которая, в свою очередь, запрашивает метаданные. выберите * из '## TmpMcsConfigurationDeviceHistory86B34BFD041A430E84CCACE78DA336A1' - person Sonam; 21.08.2013
comment
Просмотрите этот поток данных и убедитесь, выполняется ли вышеупомянутый запрос или нет. - person Sonam; 21.08.2013
comment
Просто к сведению: под табличными переменными Soram означает переменные таблицы SQL (@tables), а не переменные SSIS, содержащие DDL. - person Kyle Hale; 21.08.2013
comment
Табличные переменные отлично подходят для небольших наборов результатов. Производительность будет ужасной, если будет несколько сотен строк. - person StingyJack; 31.05.2020

Я столкнулся с аналогичной проблемой при переносе пакетов SSSI с 2008 на 2016. Последняя версия использует sp_describe_first_result_set для получения метаданных и не работает с временными таблицами. В качестве обходного пути я использовал приведенный ниже запрос в редакторе исходного кода OLEDB. Я не менял хранимую процедуру SQL, и она по-прежнему использует временную таблицу. Обязательно используйте параметр Анализировать запрос и предварительный просмотр, чтобы убедиться, что он работает нормально. См. Изображение ниже.

Запрос:

EXEC [dbo].[spGetNames]
WITH RESULT SETS((
        FirstName varchar(50), 
        LastName varchar(50)
));

См. изображение

person Raviraj Desai    schedule 22.06.2020

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

В задаче «Назначение потока данных OLE DB / ADO» указывается имя промежуточной таблицы.

Измените свойство AccessMode на команду SQL вместо OpenRowSet и укажите для свойства команды SQL значение «select * from #temp».

Ура, все работает как положено.

Уловка здесь - это когда вы указываете режим доступа, отличный от команды SQL, SSIS ожидает, что это будет таблица / представление, и изменил SSIS на вызов sp_describe_first_result_set для получения метаданных. но когда вы указываете команду SQL, она ожидает запроса или команды SP и т. д., поэтому, к счастью, он по-прежнему использует старый способ получения метаданных.

http://social.msdn.microsoft.com/Forums/sqlserver/en-US/cfe1c7c1-910a-4f52-9718-c3406263b177/usage-of-temp-tables-in-ssis-2012?forum=sqlintegrationservices#cfe1c7c1-910a-4f52-9718-c3406263b177

person vonbalaji    schedule 01.04.2014

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

Спасибо!

person Mortana    schedule 26.08.2013