SSISパッケージを使用してSQL Serverにインポートする必要がある毎月のXLSXファイルを受け取ります。残念ながら、送信者はUNCのファイル名またはワークシートの名前付けに従わず、最近のSQL Server 2012への移行により、Excel Connection Managerを使用している場合でもパッケージが失敗しました。また、テンプレートを送信しようとしましたが、そのテンプレートに従うことを拒否しており、強制的にテンプレートを使用することはできません。xlsxファイルをSQL Serverにインポートする際の問題
スクリプトタスクを使用して2つのExcelワークシートのそれぞれをSystem.Object
にインポートするパッケージを更新しようとしていますが、これをクエリまたはループスルーしてデータを出力先SQL Serverテーブル
これまでMicrosoft hereの例を使用して、Excelファイルパス/名前と両方のワークシート名をObject変数にインポートできました。ただし、ワークシートからの実際のデータセットを含むObjectは作成されません。
ここでの例とWebの他の箇所に基づいて、ワークシートデータをObject変数に出力すると思われるC#スクリプトを開始しましたが、C#ではあまり堪能ではなく、コピー元の完全な例。これは、これまでの私のコードです:
using System;
using System.Data;
using System.Data.OleDb;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
public DataSet Main()
{
string fileName;
string connectionString;
fileName = Dts.Variables["ExcelFile"].Value.ToString();
Console.WriteLine(fileName);
connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=" + fileName + ";Extended Properties=Excel 12.0 Xml";
Console.WriteLine(connectionString);
DataSet data = new DataSet();
using (OleDbConnection con = new OleDbConnection(connectionString))
{
con.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", connectionString);
adapter.Fill(data);
}
return data;
}
}
コードは正常にビルドが、私は、私は目立たエラー
Error: 0x1 at Script Task: Exception has been thrown by the target of an invocation.
Task failed: Script Task
を受けるパッケージを実行すると、私は私のConsole.WriteLine
コマンドのいずれかから任意の出力を得ることはありません、私はScript Taskがすぐに失敗すると思います。 Delay Validation = True、それを変更しても差は出ませんでした。あなたのスクリプトに明白な/初心者のエラーが表示されますか?私は何年もの間SQLとSSISを使っていましたが、私のC#/ VB/Java/etc。知識と経験は限られています。
また、私がSSIS(これは動作しないExcel Connection以外)でこれを達成するためのより良い方法を見落としている場合は、教えてください。
UPDATE - 5/31/16:今日、プロジェクトに取り掛かる時間が少しありました。少し進歩しました。私は、以下を含むために私のスクリプトタスクを更新しました:
DataSet data = new DataSet();
using (OleDbConnection con = new OleDbConnection(connectionString))
{
con.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter(query, con);
//OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [Indemnity Scores$]", con);
adapter.Fill(data);
Dts.Variables["ExcelDataTable_IndemnityScores"].Value = data;
}
スクリプトタスクは現在正常に完了したので、私はその後Foreachループコンテナを追加し、変数列挙子からforeachのにそれを設定し、コレクションとしてExcelDataTable_IndemnityScoresを選択しました。
しかし、今はこのObject変数からデータを抽出するのが難しいです。私は変数マッピングで設定した2つの列を持ちます(または少なくともはです)。また、SQLを実行するコマンドを使用して値をテーブルに挿入しています。残念ながら、各列の空白値は1つだけ挿入されます。
次に、私はExecute SQLを単純なスクリプトタスクに置き換えて、各変数の値を返しました。残念ながら、値の代わりに "Microsoft.SqlServer.Dts.Runtime.Variable"を返します。私はこれが初心者のエラーであると推測しますが、エラーを説明するオンラインのものはまだ見つかりませんでしたか?
更新日6/14/2016: 最終的にパッケージを完成し、昨日の生産で正常に実行されました。私はここで紹介されたアドバイスと他の場所で見つかった例を使用して終了しました。私の一般的なワークフローでは、ソースワークブックから両方のワークシートをインポートするためにトリプルネストされたForeachループが必要でした - 私は1ヶ月に1回しか期待していませんが、100%はこのタスクと一貫していません。
私の最も外側のループは、単にFTPプロセスによってダウンロードされたファイルを見つけるために私のインポートディレクトリを列挙します。 2つのスクリプトタスクが含まれています。最初のものは、FTPプロセスによってダウンロードされた最初のスプレッドシートのファイル名を確認するだけです。上記のMicrosoftのリンクを自分のコードに使用しましたが、私の変数名を少し変更しました。
2番目のタスクは、すべてのワークシート名を最初のスプレッドシートから取得し、上記のMicrosoftリンクを使用して作成しました。しかし、XMLデータベースが自分の変数に代入されないように、ワークシート名に "#"を付けて除外します。
第2ループ(最初の内側ループ)は、最初のループ内で解析された各ワークシート名を列挙します。これには3つのスクリプトタスクが含まれており、そのうちの最初のワークシートからのデータをオブジェクト変数にインポートします。
公共ボイドメイン(){ このループにおける第二のスクリップタスクは単にExcelから空白行を削除 {
string fileName;
string connectionString;
string worksheetName;
string query;
fileName = Dts.Variables["ExcelFile"].Value.ToString();
//MessageBox.Show("InsertWorksheetDataIntoObject - Filename: " + fileName);
connectionString = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source={0};Extended Properties=Excel 12.0 Xml;", fileName);
//MessageBox.Show("Connection: " + connectionString);
worksheetName = Dts.Variables["ExcelTable"].Value.ToString();
worksheetName = worksheetName.Replace("'", "");
//MessageBox.Show("InsertWorksheetDataIntoObject - Worksheet: " + worksheetName);
query = string.Format("SELECT * FROM [" + worksheetName + "]");
//MessageBox.Show("Query: " + query);
DataSet data = new DataSet();
using (OleDbConnection con = new OleDbConnection(connectionString))
{
con.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter(query, con);
adapter.Fill(data);
Dts.Variables["ExcelDataTable"].Value = data;
}
Dts.TaskResult = (int)ScriptResults.Success;
}
catch (Exception ex)
{
Dts.Events.FireError(-1, "ErrorMessage", ex.ToString(), "", 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}
//return data;
}
を試みます。私は上記のスクリプトでそれを組み込むことができたかもしれませんが、将来のどこかで再利用できるようにポータブルにしました。
このループの3番目のスクリプトタスクは、ワークシート名を使用して、次のループで使用される変数を設定して宛先テーブルを決定します。
第3ループ(第2内側ループ)は、ワークシートのデータを含むオブジェクト変数の行を列挙します。これには、上記のワークシート名で設定された変数値に基づいて、2つのソース列から正しい宛先表にデータをインポートする1つのSQLの実行タスクが含まれています。ワークシート名が常に一貫しているわけではないので、このループはオブジェクト変数に直接接続するため、ソース列を名前で呼び出す必要はありません。むしろ、それぞれをForeachループ内の宛先変数に割り当て、そのデータを行単位でテーブルに渡すだけです。
皆様のご協力とご援助をいただき、ありがとうございます。
このhttp://www.excel-sql-server.com/excel-import-to-sql-server-using-distributed-queries.htm(アドホック、ダイナミックパラメータ、プロセスでの許可など)を有効にしましたか? )、SSMSでそのファイルからデータを取得しますか? – gofr1