2017-02-17 2 views
0

データベースに2つのテーブルがあり、ソースはSales.Salespersonと呼ばれ、ターゲットデータベースはdbo.Salespersonです。私はC#コードを使用してソースから既存のテーブルのリストを取得し、次にすべてのデータをソースからターゲットにインポートするBIMLを作成しました。私の例では、上記の1つのテーブルしかありません。 C#で、私はSQL接続とSQLコマンドを使用してテーブルとすべてのテーブルのスキーマを取得しています(再び1のみ動的なことができます)。BIMLとC#SSISへのSQL接続とコマンド

問題があります。私のSQLコマンドで、私はBIISからSSISパッケージを生成するときに、SSISのステップEXECUTESQL DirectInputからエラーメッセージを出します。テーブルを切り捨てようとすると、<#テーブルにエラーが表示されます。 "DynamicDataLoadパッケージのSales.SalesPersonに無効な文字(/:[].=)SSISに無効な文字がwith_に置き換えられます」ANDこのため、私はここで

は、以下のコードを支援することです私のSSISパッケージにエラーが発生します:。

<Biml xmlns="http://schemas.varigence.com/biml.xsd"> 
    <Packages> 
     <Package Name="DynamicDataLoad" ConstraintMode ="Linear"   ProtectionLevel="DontSaveSensitive"> 
     <Tasks> 
      <# foreach(var table in GetTables()) { #> 
      <ExecuteSQL Name="Truncate Table Dest <#=table#>" ConnectionName="Target"> 
       **<DirectInput>Truncate Table <#=table#></DirectInput>   
      </ExecuteSQL>** 
      <Dataflow Name="Load Table <#=table#>" > 
       <Transformations> 
        <OleDbSource Name="Source Table" ConnectionName="Source"> 
         <ExternalTableInput Table="<#=table#>" /> 
        </OleDbSource> 
        <OleDbDestination Name="Destination Table" ConnectionName="Target"> 
         <ExternalTableOutput Table="<#=table#>" /> 
        </OleDbDestination> 
       </Transformations> 
      </Dataflow> 
      <# } #> 
     </Tasks> 
    </Package> 
</Packages> 
</Biml> 

以下はC#の部分ですが、SQLコマンドを見ると、上記のBIMLでSSISパッケージに変換されるすべてのテーブルを一覧表示するために使用される "table"というリストに、これは、切り詰めと呼ばれるBIMLパートで使用されます。切り詰めは、BIMLでエラーが発生した場所です。

<#+ 
List<string> GetTables() { 
    List<string> tables = new List<string>(); 

     SqlConnection cn = new SqlConnection("Data Source=mdsdqsdev;Initial Catalog=Test;Persist Security Info=False;Integrated Security=SSPI;"); 
     SqlDataAdapter da = new SqlDataAdapter(); 
     DataSet ds = new DataSet(); 
     DataTable dt = new DataTable(); 

     string q = "Select TABLE_SCHEMA+'.'+TABLE_NAME as name from INFORMATION_SCHEMA.TABLES"; 

     var cmd = new SqlCommand(q); 
     cmd.Connection = cn; 

    try 
    { 
      da.SelectCommand = cmd; 

      ds.Tables.Add(new DataTable("Results")); 

      if(cn.State != ConnectionState.Open) 
      { 
       cn.Open(); 
      } 

      ds.Tables[0].BeginLoadData(); 
      da.Fill(ds,"Results"); 
      ds.Tables[0].EndLoadData(); 

      dt = ds.Tables[0]; 

      if(cn.State != ConnectionState.Closed) 
      { 
       cn.Close(); 
      } 
    } 
    catch (Exception ex) 
    { 
     throw ex; 
    } 
    finally 
    { 
     if (cn.State != ConnectionState.Closed) 
     { 
      cn.Close(); 
     } 
     cn.Dispose(); 
    } 

    foreach (DataRow row in dt.Rows) 
    { 
     tables.Add(row["name"].ToString()); 
    } 

    return tables; 
} 

#> 
+1

問題の内容をトラッキングしていません。質問を明確にするために、しばらく時間を取って編集ボタンをクリックしてください。おそらく、あなたが使用しているコードの一部を表示してください – billinkc

+0

これは間違っているコードのサンプルを共有してください。 –

+0

コード例なしで助けが非常に不可能です。 – bc004346

答えて

0

エラーがあなたのテーブル変数がにschema.tableの形式になりますので、あなたのデータフローの名前は、あなたがしようとした場合には、「データフローFoo.Bar」ようなものになるだろう<ExecuteSQL Name="Truncate Table Dest <#=table#>" ConnectionName="Target"><Dataflow Name="Load Table <#=table#>" >によって生成されますSSDTは手動で入力することはできません。

この特定の問題に対する解決策は、文字列を「安全にする」のようにすることです。低い賃貸料のアプローチは、その期間のアンダースコアを交換するためにReplace呼び出しを適用するだけです。

<ExecuteSQL Name="Truncate Table Dest <#=table.Replace(".", "_")#>" ConnectionName="Target"> 

大きな問題は、無効な文字またはスペースが含まれているテーブルまたはスキーマです。それであなたはそれらを[]で包む必要があります。代わりに盲目的にそれらを適用するので、私は通常、より良いスキーマを持つことで務めていると私は見つけるように、テーブル名は、ディスクリート部​​品としてバック務めたことを私が発見したQUOTENAME()

Select QUOTENAME(TABLE_SCHEMA) +'.' + QUOTENAME(TABLE_NAME) as name 

でSQL Serverにその作業をプッシュします分割よりもはるかに簡単です。これにより、GetTables()のシグネチャが異なります。たぶんList<KeyValuePair<string, string>>、私は分かりません。

でも、ネイティブのBiml方法が約4行のコードである場合、私はやりたいことより多くの作業をしています。私はBimlをデータベースのreverse engineer a specific schemaに使用した例がありますが、Biml + GetDatabaseSchemaで検索すると、そうする方法の例がたくさんあります。

+0

あなたの助けを借りて大変感謝します。同じエラーメッセージは、テーブル "SELECT * FROM dbo.Orders"が見つかりませんでした無効なオブジェクトdbo.orders、これは厳しいです:(しかし、あなたのポストのために大きな感謝、今読んで、BIML、他の視点を持っていい助けが素晴らしいだろう:) – SteveB