10

SQLにインポートする必要があるひどく書かれたMSAccessデータベースを継承しました。Accessデータベースには、同一のフィールド定義を持つ数千のテーブルがあります。私はSSISの経験があり、1つのテーブルのインポートは非​​常に簡単です。

ただし、数千のテーブル名のリストをループして各テーブルをインポートできるプロセスを作成する必要があります。私はこのステートメントを見つけました、それはAccessデータベースのすべてのテーブル名のリストを取得します:

SELECT Name FROM MSysObjects WHERE(((MSysObjects.Type)= 1)AND((Left([Name]、4))<> "MSys"));

ただし、これを使用する方法がわかりません(スクリプトタスク構文?)。これを実行して、「オブジェクト」タイプのSSIS変数を設定したいと思います。そうすれば、ForEachループを使用して、このテーブルのリストを循環し、インポートを実行できます。これどうやってするの?または、データベース内の各テーブルを循環して同じプロセスを実行するためのより良い方法はありますか?

何か提案をいただければ幸いです。ありがとうございます!

4

3 に答える 3

19

Accessのすべてのテーブルが同じ構造である限り、AccessデータをSQLServerにロードする方法の1つを次に示します。この例では、Accessのテーブル、つまりCountryとをループしStateProvinceます。この例のパッケージは、これら2つのテーブルが存在しない場合はSQLで作成し、Accessからのデータを入力します。

ステップバイステップのプロセス:

  1. テーブルCountryにアクセスし、スクリーンショット# 1と#2StateProvinceに示されています。

  2. スクリーンショット# 3に示すように、SSISパッケージで、SQLServerとAccessに接続するための2つのOLEDB接続を作成します。また、スクリーンショット#4に示すように、3つの変数を作成します。変数SelectQueryでありTableName、Accessの有効なテーブルで指定する必要があります。これは、パッケージの初期構成に必要です。この場合、CountryAccessに存在するを選択しました。

  3. 変数SelectQueryを選択し、F4を押してプロパティペインを表示します。[プロパティ]ペインで、プロパティEvaluateAsExpressTrue"SELECT * FROM " + @[User::TableName]に設定し、式をプロパティに貼り付けExpressionます。この式は、現在ループスルーされているテーブルに評価されます。スクリーンショット#4を参照してください

  4. スクリーンショット#5と#6は、テーブルdbo.Countrydbo.StateProvinceがSQLServerに存在しないことを示しています。

  5. スクリーンショット# 7Control Flowに示すように、SSISパッケージのタブを構成します。を配置し、に接続します。コンテナ内に、とを配置します。Script TaskForeach Loop containerExecute SQL TaskData Flow Task

  6. スクリプトタスクのコードを、「スクリプトタスクコード」セクションに記載されているコードに置き換えます。このコードはAccessスキーマをループし、テーブル名のみをフェッチします。次に、テーブル名のリストがパッケージ変数AccessTablesに格納されます。この変数は、によって使用されForeach loop containerます。

  7. SQL Serverデータベースで、 SQLスクリプトセクションdbo.CreateTableで提供されているスクリプトを使用して名前が付けられたストアドプロシージャを作成します。このストアドプロシージャは、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. スクリーンショット# 10および#11に示すように、SQL実行タスクを構成します。

  10. テーブルがSQLServerに存在しないため、現時点ではデータフロータスクを構成できません。したがって、この時点でパッケージを実行して、Accessテーブル構造がSQLServerに作成されるようにします。スクリーンショット#12は、サンプルパッケージの実行を示しています。スクリーンショット#13は、テーブル構造がSQL Serverで作成されているが、まだデータが入力されていないことを示しています。

  11. 次に、を構成しData Flow Taskます。OLE DB SourceおよびOLE DB Destinationをデータフロータスク内に配置します。OLEDBソースをOLEDB宛先に接続します。スクリーンショット#14を参照してください。

  12. OLE DB Sourceスクリーンショット#15および#16に示すようにを構成します。

  13. OLE DB Destinationスクリーンショット#17および#18に示すようにを構成します。

  14. スクリーンショット#19は、内のサンプルパッケージ実行を示していますData Flow Task

  15. スクリーンショット#20は、SQLServerテーブルにAccessテーブルのデータが入力されていることを示しています。

この例は、構造は同じで名前が異なるテーブルに対してのみ機能します。名前付きの別のテーブルが列と。のみでAccessEmployeesに追加された場合。このサンプルパッケージを実行すると、SQL Serverに同じテーブルが作成され、データも入力されます。IdName

お役に立てば幸いです。

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

于 2011-06-10T03:30:25.777 に答える
0

SQLタスクの結果をobjectvariable型の変数に入れることができます。その変数は、ループタスクで使用できるようになります。

forループ内で、式を使用して操作しているテーブル名を変更できます。

一瞥した後、この記事ではプロセスの最初の部分について詳しく説明します。

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

于 2011-06-09T23:44:18.763 に答える
0

Accessチョップを使用している人として、最初にAccessのデータを修正し(つまり、複数のテーブルをマスターテーブルにマージし)、次にSQL Server Migration AssistantforAccessを使用してアップサイズします。これにより、実際にインポートを実行する前に、インポートをシミュレートして問題を修正できます。

データテーブルをマージする最初のステップは、VBAでコーディングするだけですが、インポートされるものをマップするメタデータを使用していくつかのテーブルを作成する必要があります(テーブルがアルゴリズムで決定できる命名規則を使用している場合を除く) )。

于 2011-06-12T21:58:51.753 に答える