2017-08-11 23 views
2

単純に言えば、私はユーザー入力を受け取り、変数に格納し、その変数をクエリで使用しようとしています。ユーザー変数を使用したSSISパッケージ

まず、簡単な入力テキストボックスとボタンを持つウィンドウを開くスクリプトタスクがあります。クリックすると、テキストがユーザー変数に入れられ、メッセージボックスがポップアップして、ユーザー変数に何が表示されているかが表示されます。メッセージボックスで[OK]をクリックすると、メッセージボックスと元のウィンドウが閉じます。これはうまくいくようです。

次に、SQL実行タスクがあります。

一般

  • のResultSet =なし
  • ConectionType = OLE DB
  • 接続を=
  • SQLSourceType =
  • のSQLStatement = [SQLコードが表示さ直接入力localhost.DB:次のように設定がされています以下]

パラメータM apping

  • 変数名=ユーザー:: VARNAME
  • 方向=入力
  • データ型= VARCHAR
  • パラメータ名= 0
  • パラメーターサイズ= 65535

結果セット - N/A

式-N/A

[SQLのCODE]

if object_id('TEST.dbo.TEST','U') is not null 
    drop table TEST.dbo.TEST; 


SELECT 
    coalesce(FSC.a, format(cast(SVY.b as int),'000')) as ab, 
    SVY.c, 
    PP.d, 
    SV1.e, 
    PP.f, 
    PP.g, 
    cast(PP.g as float) AS g, 
    SV1.h, 
    SV1.i, 
    SVY.j, 
    SVY.k, 
    format(cast(SVY.l as int), '00000') as l, 
    CAST(SVY.m AS float) AS m, 
    SVY.n, 
    SV1.o, 
    SVY.p, 

    cast(PID.q as float) as q, 
    cast(PID.r as float) as r, 
    cast(PID.s as float) as s, 
    cast(PID.t as float) as t, 

    PID.u as u, 
    PID.v as v, 

    PP.w, 

    CAL_B.x as x, 
    CAL_B.y as y, 
    CAL_B.z as z, 

    CAL_R.aa as aa, 
    CAL_R.bb as bb, 
    CAL_R.cc as cc 

into TEST.dbo.TEST 

FROM AAA.dbo.AAA PP 

INNER JOIN BBB.dbo.BBB PPC 
    ON PP.x = PPC.x 
    AND cast(PP.x as date) = cast(PPC.x as date) 

RIGHT OUTER JOIN CCC.dbo.CCC SVY 
    ON PPC.x = SVY.x 
    AND cast(PPC.x as date) = cast(SVY.x as date) 

LEFT OUTER JOIN DDD.dbo.DDD FSC 
    ON SVY.x = FSC.x 
    AND cast(SVY.x as date) = cast(FSC.x as date) 

LEFT OUTER JOIN EEE.dbo.EEE SV1 
    ON SVY.x = SV1.x 
    AND SVY.x = SV1.x 
    AND SVY.x = SV1.x 
    AND SVY.x = SV1.x 
    AND cast(SVY.x as date) = cast(SV1.x as date) 
    AND PPC.x = SV1.x 
    AND cast(PPC.x as date) = cast(SV1.x as date) 

INNER JOIN FFF.dbo.FFF RLS 
    ON SV1.x = RLS.x 
    AND SV1.x = RLS.x 
    AND cast(SV1.x as date) = cast(RLS.x as date) 
    AND SVY.x = RLS.x 
    AND SVY.x = RLS.x 
    AND SVY.x = RLS.x 
    AND cast(SVY.x as date) = cast(RLS.x as date) 

LEFT OUTER JOIN GGG.dbo.GGG PID 
    ON PP.x = PID.x 
    AND coalesce(FSC.x, format(cast(SVY.x as int),'000')) = PID.x 

LEFT OUTER JOIN HHH.dbo.HHH CAL_B 
    ON cast('20' + SUBSTRING(RLS.x,4,2) + '-' + SUBSTRING(RLS.x,6,2) + '-' + SUBSTRING(RLS.x,8,2) as date) = CAL_B.x 
    AND CAL_B.x = 1 

LEFT OUTER JOIN III.dbo.III CAL_R 
    ON cast('20' + SUBSTRING(RLS.x,4,2) + '-' + SUBSTRING(RLS.x,6,2) + '-' + SUBSTRING(RLS.x,8,2) as date) = CAL_R.x 
    AND CAL_R.x = 1 

where 
    cast(SVY.x as date) = (select cast(max(x) as date) from JJJ.dbo.JJJ) 
    and 
    PP.x is not null 
    and 
    SVY.x in (?) 

問題:私はパッケージを実行します。テキスト入力ボックスが開きます。私は自分のテキストを入れました、 "'CN05'、 'C​​N06'"(二重引用符なし)、私はOKをクリックします。私の入力を示すボックスがポップアップ表示されます。 [OK]をクリックします。ワークフローはSQL実行タスクに移動します。 1秒で、タスクは緑色のチェックで完了し、エラーは発生しません。私は、TEST.dbo.TESTが作成されているが、空であることを確認します。 最後のビット[... SVY.x in( 'CN05'、 'C​​N06')をハードコードするSSMSで上記のコードを実行すると、約4分で500万を超えるレコードを取り戻すことができます。なぜSSISでこれが動作していないのか、私は困惑しています。そこに任意のアイデア?

答えて

3

一般に、パラメータ化されたWHERE INdon't play nice。彼らは私たちが考えるべき方法で決して働かない。代わりに、SSISのバージョンの動的SQLを使用して同じことを達成できます。より大きいSQLステートメントのユーザー入力との連結を格納する文字列変数を作成します。次に、この変数を使用するようにExecute SQL Taskを配線します。

たとえば、SqlStatementという新しいSSIS文字列変数を作成してください。変数のプロパティウィンドウで、楕円をクリックして式ビルダーウィンドウを開きます。この式ビルダーを使用して、SQLとユーザー入力を連結します。下のサンプル...

enter image description here

Trueに変数のEvaluateAsExpressionプロパティを設定してください。

enter image description here

最後に、変数への直接入力からあなたのSQL実行タスクを切り替えると、ソースとしてこの変数を選択します。

Thing.

すべてのセット。式ビルダーの内部で作成した動的SQLを使用するために、SQL実行タスクを配線する必要があります。がんばろう!

+0

ありがとうトロイ!魅力のように動作します。私の方法がうまくいかない理由についての追加情報をありがとう。 SQLについて毎日何か新しいことを学んでください。 –

+0

うれしい私は助けることができました。私はあなたが構築しているツールは内部的なので、大したことではないという印象を受けますが、ユーザー入力を受け取り、動的SQLを使用しているので、少しの[SQLインジェクション保護](https:// www .owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet)。おそらく、フィルタアウトしたり、 '' '文字や'; '文字を取り除いてください。 –

関連する問題