Как разбить большой набор данных на несколько таблиц Excel с помощью пакета служб SSIS? - PullRequest
2 голосов
/ 12 июля 2011

У меня проблема с пакетом служб SSIS.

  • Запрос выполняется для получения некоторых данных из базы данных (SQL Server 2008) (задание потока данных выполнено)
  • Экспорт данных, извлеченных в электронную таблицу Excel 97-2003 (.xls), с использованием Excel Destination

Как большинство из вас знает, файлы xls ограничены на листе 65 536 строками по 256 столбцам. Поэтому, когда запрос извлекает больше, чем предел записей (65 536), шаг назначения Excel завершается неудачей.

Я получаю следующие сообщения об ошибках.

Error: 0xC0202009 at Calidad VIDA, Excel Destination [82]: SSIS Error Code DTS_E_OLEDBERROR. An OLE DB error has occurred. Error code: 0x80004005.

Error: 0xC0209029 at Calidad VIDA, Excel Destination [82]: SSIS Error Code DTS_E_INDUCEDTRANSFORMFAILUREONERROR. The "input "Excel Destination Input" (93)" failed because error code 0xC020907B occurred, and the error row disposition on "input "Excel Destination Input" (93)" specifies failure on error. An error occurred on the specified object of the specified component. There may be error messages posted before this with more information about the failure. Error: 0xC0047022 at Calidad VIDA, SSIS.Pipeline: SSIS Error Code DTS_E_PROCESSINPUTFAILED. The ProcessInput method on component "Excel Destination" (82) failed with error code 0xC0209029 while processing input "Excel Destination Input" (93). The identified component returned an error from the ProcessInput method. The error is specific to the component, but the error is fatal and will cause the Data Flow task to stop running. There may be error messages posted before this with more information about the failure.

Error: 0xC02020C4 at Calidad VIDA, OLE DB Source [1]: The attempt to add a row to the Data Flow task buffer failed with error code 0xC0047020.

Error: 0xC0047038 at Calidad VIDA, SSIS.Pipeline: SSIS Error Code DTS_E_PRIMEOUTPUTFAILED. The PrimeOutput method on component "OLE DB Source" (1) returned error code 0xC02020C4. The component returned a failure code when the pipeline engine called PrimeOutput(). The meaning of the failure code is defined by the component, but the error is fatal and the pipeline stopped executing. There may be error messages posted before this with more information about the failure.

Файл должен быть в этом формате, потому что у клиентов нет более новых версий. И они не хотят покупать лицензии. Кто-нибудь знает, как обойти эту проблему? Я должен использовать задачу «Сценарий» и сделать Excel самостоятельно, или я должен создать для каждого цикла и создать различные рабочие книги?

Ответы [ 3 ]

6 голосов
/ 13 июля 2011

Вот один из возможных вариантов, который можно использовать для динамического создания листов Excel с использованием служб SSIS в зависимости от того, сколько записей вы хотите записать на лист Excel.Это не связано с задачами сценария.В следующем примере описывается, как этого можно достичь с помощью задач «Выполнение SQL», контейнера For Loop и задачи «Поток данных».Пример был создан с использованием SSIS 2008 R2.

Пошаговый процесс:

  1. В базе данных SQL Server запустите сценарии, представленные в разделе SQL-сценарии раздел.Эти сценарии создадут таблицу с именем dbo.SQLData, а затем заполнят таблицу данными умножения от 1 x 1 до 20 x 40, создавая таким образом 800 записей.Сценарий также создает хранимую процедуру с именем dbo.FetchData, которая будет использоваться в пакете служб SSIS.

  2. В пакете служб SSIS создайте переменные 9 , как показано на снимке экрана# 1 .Следующие шаги описывают настройку каждой из этих переменных.

  3. Установите переменную ExcelSheetMaxRows со значением 80 .Эта переменная представляет количество строк для записи на лист Excel.Вы можете установить его на значение по вашему выбору.В вашем случае это будет 65 535 (вы можете оставить одну строку для имен столбцов заголовков).

  4. Установить переменную SQLFetchTotalRows со значением SELECT COUNT(Id) AS TotalRows FROM dbo.SQLData.Эта переменная содержит запрос для извлечения общего количества строк из таблицы.

  5. Выберите переменную StartIndex и выберите Свойства, нажав F4 .Установите для свойства EvaluateAsExpression значение True, а для свойства Expression - значение (@[User::Loop] * @[User::ExcelSheetMaxRows]) + 1.См. Скриншот # 2 .

  6. Выберите переменную EndIndex и выберите Свойства, нажав F4 .Установите для свойства EvaluateAsExpression значение True, а для свойства Expression - значение (@[User::Loop] + 1) * @[User::ExcelSheetMaxRows].См. Снимок экрана # 3 .

  7. Выберите переменную ExcelSheetName и выберите Свойства, нажав F4 .Установите для свойства EvaluateAsExpression значение True, а для свойства Expression - значение "Sheet" + (DT_WSTR,12) (@[User::Loop] + 1).См. Снимок экрана # 4 .

  8. Выберите переменную SQLFetchData и выберите Свойства, нажав F4 .Установите для свойства EvaluateAsExpression значение True, а для свойства Expression - значение "EXEC dbo.FetchData " + (DT_WSTR, 15) @[User::StartIndex] + "," + (DT_WSTR, 15) @[User::EndIndex].См. Снимок экрана # 5 .

  9. Выберите переменную ExcelTable и выберите Свойства, нажав F4 .Задайте для свойства EvaluateAsExpression значение True, а для свойства Выражение - значение, указанное в разделе Значение переменной ExcelTable .См. Снимок экрана # 6 .

  10. На вкладке Поток управления пакета служб SSIS поместите задачу «Выполнение SQL» и настройте ее, как показано на снимках экрана # 7 и # 8 .Эта задача извлекает количество записей.

  11. На вкладке «Поток управления» в пакете служб SSIS поместите контейнер For Loop и настройте его, как показано на скриншоте # 9 .Обратите внимание, что это для цикла , а не цикл по каждому элементу.Этот цикл будет выполняться на основе количества записей, отображаемых на каждом листе Excel, вместе с общим количеством записей, найденных в таблице.

  12. Создание электронной таблицы Excel Excel 97-2003формат, содержащий расширение .xls, как показано на скриншоте # 10 .Я создал файл в ** C: \ temp **

  13. В диспетчере соединений пакета служб SSIS создайте соединение OLE DB с именем SQLServer, указывающее на SQL Server, и соединение Excel с именемExcel указывает на вновь созданный файл Excel.

  14. Нажмите на подключение Excel и выберите Свойства.Изменяет свойство DelayValidation с False на True, чтобы при переключении на использование переменной для создания листа в Задаче потока данных мы не получали никаких сообщений об ошибках.См. Снимок экрана # 11 .

  15. Внутри контейнера For Loop поместите задачу «Выполнение SQL» и настройте ее, как показано на снимке экрана # 12 .Эта задача создаст таблицы Excel в соответствии с требованиями.

  16. Внутри контейнера For Loop поместите задачу потока данных.После настройки задач вкладка «Поток управления» должна выглядеть так, как показано на снимке экрана # 13 .

  17. Внутри задачи потока данных поместите источник OLE DB вчитать данные из SQL Server с помощью хранимой процедуры.Настройте источник OLE DB, как показано на снимках экрана # 14 и # 15 .

  18. Внутри задачи потока данных поместите пункт назначения Excel ввставьте данные в листы Excel.Настройте пункт назначения Excel, как показано на снимках экрана # 16 и # 17 .

  19. После настройки задачи потока данных она должна выглядеть следующим образомкак показано на скриншоте # 18 .

  20. Удалите файл Excel, созданный на шаге 12 , поскольку пакет автоматически создаст файл приказнены.Если не удалить, пакет выдаст исключение, что Sheet1 уже существует.В этом примере используется путь C: \ temp \, а на снимке экрана # 19 показано, что по этому пути нет файлов.

  21. Снимки экрана # 20 и # 21 показывают выполнение пакета в задачах Поток управления и Поток данных.

  22. Снимок экрана # 22 * ​​1213 * показывает, что файл ExcelData.xls былсозданный в пути C: \ temp.Помните, раньше этот путь был пуст.Поскольку в таблице было 800 строк, и мы установили переменную пакета ExcelSheetMaxRows , чтобы создать 80 строк на листе.Следовательно, файл Excel имеет 10 листов.См. Снимок экрана # 23 .

  23. NOTE: Одна вещь, которую я не сделал в этом примере, это проверить, является ли файл ExcelData.xls уже существует в пути C: \ temp.Если он существует, файл должен быть удален перед выполнением задач.Это может быть достигнуто путем создания переменной, содержащей путь к файлу Excel, и использования задачи «Файловая система» для удаления файла перед выполнением первой задачи «Выполнение SQL».

Надеюсь, это поможет.

Значение переменной ExcelTable:

"CREATE TABLE `" + @[User::ExcelSheetName] + "`(`Id` Long, `Number1` Long, `Number2` Long, `Value` Long)"

Сценарии SQL:

--Create table

CREATE TABLE [dbo].[SQLData](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Number1] [int] NOT NULL,
    [Number2] [int] NOT NULL,
    [Value] [int] NOT NULL,
CONSTRAINT [PK_Multiplication] PRIMARY KEY CLUSTERED ([Id] ASC)) ON [PRIMARY]
GO

--Populate table with data

SET NOCOUNT ON

DECLARE @OuterLoop INT
DECLARE @InnerLoop INT
SELECT @OuterLoop = 1

WHILE @OuterLoop <= 20 BEGIN

    SELECT @InnerLoop = 1   
    WHILE @InnerLoop <= 40 BEGIN

            INSERT INTO dbo.SQLData (Number1, Number2, Value)
            VALUES (@OuterLoop, @InnerLoop, @OuterLoop * @InnerLoop)

            SET @InnerLoop = @InnerLoop + 1
    END

    SET @OuterLoop = @OuterLoop + 1
END

SET NOCOUNT OFF

--Create stored procedure

CREATE PROCEDURE [dbo].[FetchData]
(
        @StartIndex INT
    ,   @EndIndex   INT
)
AS
BEGIN

    SELECT  Id
        ,   Number1
        ,   Number2
        ,   Value
    FROM    (
                SELECT  RANK() OVER(ORDER BY Id) AS RowNumber
                    ,   Id
                    ,   Number1
                    ,   Number2
                    ,   Value 
                FROM    dbo.SQLData
            ) T1
    WHERE   RowNumber BETWEEN @StartIndex AND @EndIndex
END
GO

Снимок экрана № 1:

1

Снимок экрана № 2:

2

Снимок экрана № 3:

3

Снимок экрана № 4:

4

Снимок экрана № 5:

5

Снимок экрана № 6:

6

Снимок экрана № 7:

7

Снимок экрана № 8:

8

Снимок экрана № 9:

9

Снимок экрана № 10:

10

Снимок экрана № 11:

11

Снимок экрана № 12:

12

Снимок экрана № 13:

13

Снимок экрана № 14:

14

Скриншот № 15:

15

Снимок экрана № 16:

16

Снимок экрана № 17:

17

Снимок экрана № 18:

18

Снимок экрана № 19:

19

Снимок экрана № 20:

20

Снимок экрана № 21:

21

Снимок экрана № 22:

22

Снимок экрана № 23:

23

2 голосов
/ 12 июля 2011

Опция рендеринга Stock Excel позволяет разбивать страницы на отдельные вкладки. Если вы принудительно разрываете страницу после соответствующего числа строк, вы получаете новую вкладку для каждой «страницы» в выходных данных. У меня нет настроек, которые я использовал для этого в прошлом, но я могу посмотреть их завтра, если понадоблюсь.

0 голосов
/ 17 февраля 2012

Для меня также было полезно использовать пакет служб SSIS для экспорта в файл CSV, а затем вручную импортировать данные в Excel.Обратите внимание, что это не то же самое, что «Открыть» в Excel, потому что это также просто остановится на 65536 строк.Создайте новый файл xlsx и нажмите «Данные» -> «Из текста».Это импортирует и покажет все строки.Протестировано с 750 000 строк.

Однако не уверен, что преобразование csv -> xlsx легко записывается в пакет SSIS.Скорее всего через задачу «Сценарий» с использованием COM-объекта Excel.

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