web-dev-qa-db-ja.com

SSIS制御フロータスクで一時テーブルを作成し、それをデータフロータスクで使用する方法は?

T-SQLコマンドを使用して一時データベースとテーブルを作成する制御フローがあります。データフローを追加するとき、テーブルをクエリしたいのですが、情報を取得するためのテーブルが存在しないためできません。データベースを(まだ)存在しないため、ログインしようとするとエラーが発生します。遅延検証をtrueにしています。

データベースとテーブルを手動で作成し、クエリを使用してデータフローを追加し、データベースをドロップすると、それは固執しますが、きれいな解決策ではないようです。

一時的なステージングデータベースを作成し、データフローでクエリするより良い方法がある場合はお知らせください。

37
bep

解決:

_Connection Manager_のプロパティRetainSameConnectionTrueある制御フロータスクで作成された一時テーブルを別のタスクで保持できるようにします。

_SSIS 2008 R2_で記述されたサンプルSSISパッケージは、一時テーブルの使用を示しています。

チュートリアル:

_##tmpStateProvince_という名前の一時テーブルを作成し、いくつかのレコードを取り込むストアドプロシージャを作成します。サンプルSSISパッケージは、最初にストアドプロシージャを呼び出し、次に一時テーブルデータをフェッチして、レコードを別のデータベーステーブルに取り込みます。サンプルパッケージはSoraという名前のデータベースを使用します。以下のストアドプロシージャ作成スクリプトを使用します。

_USE Sora;
GO

CREATE PROCEDURE dbo.PopulateTempTable
AS
BEGIN

    SET NOCOUNT ON;

    IF OBJECT_ID('TempDB..##tmpStateProvince') IS NOT NULL
        DROP TABLE ##tmpStateProvince;

    CREATE TABLE ##tmpStateProvince
    (
            CountryCode     nvarchar(3)         NOT NULL
        ,   StateCode       nvarchar(3)         NOT NULL
        ,   Name            nvarchar(30)        NOT NULL
    );

    INSERT INTO ##tmpStateProvince 
        (CountryCode, StateCode, Name)
    VALUES
        ('CA', 'AB', 'Alberta'),
        ('US', 'CA', 'California'),
        ('DE', 'HH', 'Hamburg'),
        ('FR', '86', 'Vienne'),
        ('AU', 'SA', 'South Australia'),
        ('VI', 'VI', 'Virgin Islands');
END
GO
_

_dbo.StateProvince_という名前のテーブルを作成します。このテーブルは、一時テーブルからレコードを取り込むための宛先テーブルとして使用されます。以下のテーブル作成スクリプトを使用して、宛先テーブルを作成します。

_USE Sora;
GO

CREATE TABLE dbo.StateProvince
(
        StateProvinceID int IDENTITY(1,1)   NOT NULL
    ,   CountryCode     nvarchar(3)         NOT NULL
    ,   StateCode       nvarchar(3)         NOT NULL
    ,   Name            nvarchar(30)        NOT NULL
    CONSTRAINT [PK_StateProvinceID] PRIMARY KEY CLUSTERED
        ([StateProvinceID] ASC)
) ON [PRIMARY];
GO
_

Business Intelligence Development Studio (BIDS)を使用してSSISパッケージを作成します。パッケージの下部にある[接続マネージャー]タブを右クリックし、_New OLE DB Connection..._をクリックして、アクセスする新しい接続を作成しますSQL Server 2008 R2データベース。

Connection Managers - New OLE DB Connection

_New..._ on Configure OLE DB Connection Manager]をクリックします。

Configure OLE DB Connection Manager - New

Connection Managerダイアログで次のアクションを実行します。

  • パッケージはSQL Server 2008 R2データベースに接続するため、_Native OLE DB\SQL Server Native Client 10.0_ from Providerを選択します
  • _MACHINENAME\INSTANCE_のようなサーバー名を入力します
  • サーバーへのログオンセクションまたは任意のセクションから_Use Windows Authentication_を選択します。
  • _Select or enter a database name_からデータベースを選択します。サンプルはデータベース名Soraを使用します。
  • _Test Connection_をクリックします
  • テスト接続に成功しましたメッセージでOKをクリックします。
  • OK on 接続マネージャをクリックします

Connection Manager

新しく作成されたデータ接続がConfigure OLE DB Connection Managerに表示されます。OKをクリックします。

Configure OLE DB Connection Manager - Created

OLE DB接続マネージャー_KIWI\SQLSERVER2008R2.Sora_は、パッケージの下部にある接続マネージャータブの下に表示されます。接続マネージャーを右クリックし、Propertiesをクリックします

Connection Manager Properties

接続のプロパティRetainSameConnectionを設定します_KIWI\SQLSERVER2008R2.Sora_を値True

RetainSameConnection Property on Connection Manager

パッケージ内の任意の場所を右クリックし、[Variables]をクリックして変数ペインを表示します。以下の変数を作成します。

  • PopulateTempTableという名前のデータ型の新しい変数Stringパッケージスコープ_SO_5631010_変数に値_EXEC dbo.PopulateTempTable_を設定します。

  • FetchTempDataという名前のデータ型の新しい変数Stringパッケージスコープ_SO_5631010_変数を値_SELECT CountryCode, StateCode, Name FROM ##tmpStateProvince_で設定します

Variables

_Execute SQL Task_Control Flowタブにドラッグアンドドロップします。 SQL実行タスクをダブルクリックして、SQLタスク実行エディターを表示します。

SQLタスクエディタの実行Generalページで、次のアクションを実行します。

  • Name_Create and populate temp table_に設定します
  • 接続タイプ_OLE DB_に設定します
  • 接続_KIWI\SQLSERVER2008R2.Sora_に設定します
  • VariableからSQLSourceTypeを選択します
  • _User::PopulateTempTable_ from SourceVariableを選択します
  • OKをクリックします

Execute SQL Task Editor

_Data Flow Task_Control Flowタブにドラッグアンドドロップします。データフロータスクの名前を_Transfer temp data to database table_に変更します。 SQLタスクの実行から緑の矢印をデータフロータスクに接続します。

Control Flow Tab

_Data Flow Task_をダブルクリックして、データフロータブに切り替えます。 _OLE DB Source_Data Flowタブにドラッグアンドドロップします。 OLE DB Sourceをダブルクリックして、OLE DB Source Editorを表示します。

OLE DB Source Editor_Connection Manager_ページで、次のアクションを実行します。

  • _KIWI\SQLSERVER2008R2.Sora_ from OLE DB Connection Managerを選択します
  • _SQL command from variable_を選択しますデータアクセスモード
  • _User::FetchTempData_を選択します変数名
  • Columnsページをクリックします

OLE DB Source Editor - Connection Manager

ColumnsのページOLE DB Source Editorをクリックすると、テーブル_##tmpStateProvince_ソースコマンド変数で指定されたものが存在せず、SSISが列定義を読み取れません。

Error message

エラーを修正するには、データベースでSQL Server Management Studio(SSMS)を使用してステートメント_EXEC dbo.PopulateTempTable_を実行しますSoraこれにより、ストアドプロシージャは一時テーブルを作成します。ストアドプロシージャを実行した後、ColumnsOLE DB Source Editorのページをクリックすると、列情報が表示されます。 OKをクリックします。

OLE DB Source Editor - Columns

_OLE DB Destination_Data Flowタブにドラッグアンドドロップします。緑の矢印をOLE DB SourceからOLE DB Destinationに接続します。 _OLE DB Destination_をダブルクリックして開きますOLE DB Destination Editor

OLE DB Destination Editor_Connection Manager_ページで、次のアクションを実行します。

  • _KIWI\SQLSERVER2008R2.Sora_ from OLE DB Connection Managerを選択します
  • _Table or view - fast load_を選択しますデータアクセスモード
  • _[dbo].[StateProvince]_ from Name from the table or view
  • Mappingsページをクリックします

OLE DB Destination Editor - Connection Manager

MappingsOLE DB Destination Editorをクリックすると、入力列名と出力列名が同じ場合に列が自動的にマップされます。 OKをクリックします。列StateProvinceIDには一致する入力列がなく、データベースのIDENTITY列として定義されています。したがって、マッピングは必要ありません。

OLE DB Destination Editor - Mappings

データフロータブは、すべてのコンポーネントを構成した後、次のようになります。

Data Flow tab

データフロータブの_OLE DB Source_をクリックし、F4を押してPropertiesを表示します。プロパティValidateExternalMetadataをFalseに設定して、SSISがパッケージ実行の検証フェーズ中に一時テーブルの存在をチェックしないようにします。

Set ValidateExternalMetadata

SQL Server Management Studio(SSMS)で_select * from dbo.StateProvince_クエリを実行して、テーブル内の行数を見つけます。パッケージを実行する前に空にする必要があります。

Rows in table before package execution

パッケージを実行します。制御フローは実行の成功を示します。

Package Execution - Control Flow tab

[データフロー]タブで、パッケージが6行を正常に処理したことがわかります。この投稿の早い段階で作成されたストアドプロシージャは、6行を一時テーブルに挿入しました。

Package Execution - Data Flow tab

SQL Server Management Studio(SSMS)でクエリ_select * from dbo.StateProvince_を実行して、テーブルに正常に挿入された6行を見つけます。データは、ストアドプロシージャで見つかった行と一致する必要があります。

Rows in table after package execution

上記の例は、パッケージ内で一時テーブルを作成して使用する方法を示しています。

120
user756519

私はこのパーティーに遅れていますが、user756519の徹底した優れた回答に少し加えたいと思います。私の最近の経験に基づいて、このインスタンスに「接続マネージャーのRetainSameConnection」プロパティが関連しているとは思わない。私の場合、関連するポイントは、「ValidateExternalMetadata」をFalseに設定するというアドバイスでした。

一時テーブルを使用して、あるデータベース(およびサーバー)から別のデータベース(およびサーバー)へのデータのコピーを容易にしているため、特定のケースでは「RetainSameConnection」の理由は関係ありません。そして、この例で起こっていることを、それができる限り徹底的に達成することも重要だとは思いません。

0
DigginDev