Как программно получить список таблиц MS Access в пакете служб SSIS? - PullRequest
8 голосов
/ 10 июня 2011

Я унаследовал ужасно написанную базу данных MS Access, которую мне нужно импортировать в SQL. База данных Access содержит несколько тысяч таблиц с одинаковыми определениями полей. У меня есть некоторый опыт работы с SSIS, и импортировать одну таблицу довольно просто.

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

ВЫБРАТЬ Имя ИЗ MSysObjects WHERE (((MSysObjects.Type) = 1) И ((Слева ([Имя], 4)) <> «MSys»));

Однако я не уверен, как это использовать (синтаксис задачи скрипта?). Я думаю, я бы хотел сделать это, чтобы заполнить переменную SSIS типа «объект». Таким образом, я могу использовать цикл ForEach для циклического перемещения по этому списку таблиц и выполнения импорта. Как я могу это сделать? Или есть лучший способ циклически проходить по каждой таблице в базе данных и выполнять один и тот же процесс?

Буду очень признателен за любые предложения. Спасибо тебе!

Ответы [ 3 ]

17 голосов
/ 10 июня 2011

Вот один из возможных способов загрузки данных Access в SQL Server, если все таблицы в Access имеют одинаковую структуру.В этом примере будут циклически проходить таблицы в Access, а именно Country и StateProvince.Пакет в этом примере создаст эти две таблицы в SQL, если они не существуют, а затем заполнит их данными из Access.

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

  1. Таблицы доступа Country и StateProvince показаны на снимках экрана # 1 и # 2 .

  2. В пакете служб SSIS создайте два подключения OLE DB для подключения к SQL Server и Access, как показано на снимке экрана # 3 .Также создайте 3 переменные, как показано на скриншоте # 4 .Переменные SelectQuery и TableName должны быть указаны в допустимой таблице в Access.Это необходимо для начальной настройки пакета.Здесь, в этом случае, я выбрал Country, который существует в Access.

  3. Выберите переменную SelectQuery и нажмите F4, чтобы просмотреть панель свойств.На панели свойств установите для свойства EvaluateAsExpress значение True и вставьте выражение "SELECT * FROM " + @[User::TableName] в свойство Expression.Это выражение будет соответствовать таблице, в которой в данный момент выполняется цикл.Смотрите скриншоты # 4

  4. Скриншоты # 5 и # 6 показывают, что таблицы dbo.Country и dbo.StateProvince не существует в SQL Server.

  5. Настройте вкладку Control Flow пакета служб SSIS, как показано на снимке экрана # 7 .Поместите Script Task и подключите его к Foreach Loop container.Внутри контейнера поместите Execute SQL Task и Data Flow Task.

  6. Замените код в задаче сценария на код, указанный в разделе «Код задачи скрипта».Этот код будет зацикливать схему доступа и извлекать только имена таблиц.Список имен таблиц затем сохраняется в переменной пакета AccessTables, которая затем будет использоваться Foreach loop container.

  7. В базе данных SQL Server создайте хранимую процедуру с именем dbo.CreateTableиспользуя скрипт из раздела SQL Scripts .Эта хранимая процедура создаст таблицу в SQL Server, если она еще не существует.Make sure that you alter the table schema defined in the stored procedure according to your needs.

  8. Настройте Foreach loop container, как показано на снимках экрана # 8 и # 9 .

  9. Настройка задачи «Выполнение SQL», как показано на снимках экрана # 10 и # 11 .

  10. Мы не можем настроить задачу потока данных вэтот момент, потому что таблицы не существуют в SQL Server.Итак, мы выполним пакет на этом этапе, чтобы структуры таблицы Access были созданы в SQL Server.Снимок экрана # 12 показывает пример выполнения пакета.Снимок экрана # 13 показывает, что структуры таблиц созданы в SQL Server, но они еще не заполнены данными.

  11. Теперь мы настроим Data Flow Task,Поместите OLE DB Source и OLE DB Destination в Задачу потока данных.Подключите источник OLE DB к назначению OLE DB.Смотрите скриншот # 14 .

  12. Настройте OLE DB Source, как показано на скриншотах # 15 и # 16 .

  13. Настройте OLE DB Destination, как показано на скриншотах # 17 и # 18 .

  14. Снимок экрана # 19 показывает пример выполнения пакета в Data Flow Task.

  15. Снимок экрана # 20 показывает, что таблицы SQL Server теперь заполнены даннымииз таблиц доступа.

Этот пример будет работать только для таблиц, имеющих одинаковую структуру, но различающихся по имени.Если к Access добавится еще одна таблица с именем Employees, содержащая только столбцы Id и Name.Выполнение этого примера пакета создаст ту же таблицу в SQL Server, а также заполнит ее данными.

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

Сценарии SQL:

CREATE PROCEDURE [dbo].[CreateTable]
(
    @TableName  VARCHAR(255)
)
AS
BEGIN

    SET NOCOUNT ON

    DECLARE @SQL VARCHAR(MAX)

    SET @SQL = 'IF NOT EXISTS ( SELECT  * 
                                FROM    sys.objects 
                                WHERE   object_id = OBJECT_ID(N''[dbo].' + @TableName + ''') 
                                AND     type in (N''U''))
                    CREATE TABLE [dbo].' + @TableName + '(
                        [ID] [int] NOT NULL,
                        [Name] [nvarchar](255) NULL
                        ) ON [PRIMARY]'

    EXEC (@SQL)
END
GO

Код задачи сценария:

C # код, который можно использовать только в SSIS 2008 and above.

/*
   Microsoft SQL Server Integration Services Script Task
   Write scripts using Microsoft Visual C# 2008.
   The ScriptMain is the entry point class of the script.
*/

using System;
using System.Collections;
using System.Data;
using System.Data.OleDb;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;

namespace ST_9b2714c55db14556be74ca92f345c4e3.csproj
{
    [System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {

        #region VSTA generated code
        enum ScriptResults
        {
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        };
        #endregion

        public void Main()
        {
            Variables varCollection = null;
            DataTable schemaTables = null;
            ArrayList tableNames = new ArrayList();

            Dts.VariableDispenser.LockForWrite("User::AccessTables");
            Dts.VariableDispenser.GetVariables(ref varCollection);

            using (OleDbConnection connection = new OleDbConnection(Dts.Connections["AccessDB"].ConnectionString.ToString()))
            {
                string[] restrictions = new string[4];
                restrictions[3] = "Table";    
                connection.Open();
                schemaTables = connection.GetSchema("Tables", restrictions);
            }

            foreach (DataRow row in schemaTables.Rows)
            {
                foreach (DataColumn column in schemaTables.Columns)
                {
                    if (column.ColumnName.ToUpper() == "TABLE_NAME")
                    {
                        tableNames.Add(row[column].ToString());
                    }
                }
            }

            varCollection["User::AccessTables"].Value = tableNames;

            Dts.TaskResult = (int)ScriptResults.Success;
        }
    }
}

Скриншот № 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

0 голосов
/ 13 июня 2011

Как кто-то, у кого есть доступ к Access, я сначала исправил бы данные в Access (то есть объединил несколько таблиц в главные таблицы), а затем использовал помощника по миграции SQL Server для Access для увеличения размера.Он позволяет вам смоделировать импорт и исправить любые проблемы до того, как вы на самом деле это сделаете.

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

0 голосов
/ 10 июня 2011

Вы можете поместить результаты задачи sql в переменную типа переменная объекта . Затем эта переменная будет доступна для использования в задаче цикла.

Внутри цикла for вы можете изменить имя таблицы, с которой вы работаете, используя выражения .

После быстрого просмотра этой статьи может быть подробно описана первая часть процесса:

http://www.sqlservercentral.com/articles/Integration+Services+(SSIS)/64014/

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