私はC#...を介してスプレッドシートファイルを読んでいます。スプレッドシートは1000行以上あります。私は、いくつかのデータベース側のロジックを実行し、レコードを更新するために、各行のデータをストアドプロシージャに送信する必要があります。私は時間を節約するために、1回の往復で1000行のデータをすべて送信するためにいくつかの助けが必要です。これらのすべての1000行のデータをグループ化する必要がある技術は何ですか。データのバルク行をストアドプロシージャに渡す
答えて
SQL Server 2008以降を使用していると推測すると、いくつかの選択肢があります。これらのオプションはすべて、ニューオーリンズのTech-Ed 2010およびvideo of the session is available onlineで詳細に説明されています。以下は提示されたオプションの要約です。
オプション#1 - あなただけのテーブルにデータを「ダンプ」する必要があり、あなたは多くを行う必要がない場合は、一括挿入(本当にvideoに記載されていない)
これは素晴らしい選択肢ですデータをデータベースに取り込むことを除いて、これは、SqlBulkCopyオブジェクトを使用するADO.NETでもサポートされています。
は、すべてのデータを取り、大きな文字列を構築し、文字列全体を渡す区切りのリストを渡します - 私はまた、より簡単に
オプション#2 lightweight wrapper you can find on CodePlexは、SQL ServerとADO.NETでの作業にするために書かれていますストアドプロシージャに格納します。これは驚くほど速いですが、多くの手荷物が付いてきます。データを取得し、SQL-CLRで分割するのに必要な最高のパフォーマンスを得るには、分割機能が必要です。データベースを所有していない場合は、showstopperにすることができます。
オプション#3 - あなたは再び一つのパラメータに巨大な文字列で渡しているので、これはオプション#2とほぼ同じであるXML
として渡します。これには妥当なパフォーマンスもありますが、Option#2と同じ手荷物の多くは、SQL ServerがXMLの解析方法を知っているため、分割機能はありません。
オプション#4 - このオプションは、非常にクールで、最高のパフォーマンスを提供します。表値関数(SQL Server 2008の)
を使用してください。まず、SQL Serverで "テーブル"型の値型を作成し、その値の型をパラメータとして持つストアドプロシージャを作成します。 C#では、SqlCommandを作成し、SqlDbType.Structured型のパラメータを追加できます。
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Test.spTVP";
var p = cmd.Parameters.Add("@Values", SqlDbType.Structured);
p.TypeName = "Test.OrderTableType";
p.Value = dataTable;
cmd.Execute…;
ストアドプロシージャが実行されると、すべてのデータがストアドプロシージャのテーブル変数で使用できます。他のテーブル変数と同様に使用することができ、データの移動は非常に簡単です。
オプション#5からストリーミング表値関数(SQL Server 2008の)
を使用してもう少し作業後、オプション#4あなたはセットアップにイテレータを持っていますが、外にいくつかのクレイジーなパフォーマンスを得るため、ストアドプロシージャに渡す前にすべてのデータをクライアントにロードする必要がないためです。 .NETランタイムは実際にデータをデータベースにストリーミングし、ストアドプロシージャの実装は同じです。
class MyStreamingTvp : IEnumerable<SqlDataRecord> { …
}
…
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Test.spTVP";
var p = cmd.Parameters.Add("@Values", SqlDbType.Structured);
p.TypeName = "Test.OrderTableType";
p.Value = new MyStreamingTvp(…);
cmd.Execute…;
これらのオプションはすべて、非常に詳細と私は冒頭で述べたvideoで少しユーモアで覆われています。今年Tech-Edで私が気に入ったセッションのひとつでした。
+1:非常に良いオプション、私はもっと投票できることを願っています – TalentTuner
@Saurabh私はあなたのためにそれをしました:-) –
こんにちはライアン、非常に良い答え!ちょうどビデオのリンクがもう働いていません。あなたは新しいリンクを投稿してもらえますか、それともあなたはまだセッションのタイトルを知っていますか?セッションのビデオはまだcannel9にあるはずです... – Markus
ライアンの答えは非常に徹底的で、さまざまなオプションをカバーしています。比較的少数の行(1000-5000はかなり小さいとみなされます)では、ストアドプロシージャのパラメータとしてXMLを渡して、オプション#3として概説されているものを使用します。
私はあなたのスプレッドシートのデータがシンプルで、あなたが作成したリストのようなものとしてあなたのコード内にすぐに用意されていると仮定しています。 DataTable。この簡単な例では、データを簡単にするためにDataTableと仮定します。
私は、ライアンのように、また、SQL 2008
1を想定しています - ストアドプロシージャに渡されるXMLにデータを変換することにより、C#でデータを準備します。これは単なるXML文字列です。私たちは基本データクラスのメソッドを使います。 DataTableを渡すと、ストアドプロシージャのパラメータとして渡すことができる単純なXML文字列に変換されます。
public string ConvertToXMLDataString(DataTable table) {
StringBuilder XMLString = new StringBuilder();
if (string.IsNullOrEmpty(table.TableName))
table.TableName = "DataTable";
XMLString.AppendFormat("<{0}>", table.TableName);
DataColumnCollection tableColumns = table.Columns;
foreach (DataRow row in table.Rows) {
XMLString.AppendFormat("<RowData>");
foreach (DataColumn column in tableColumns) {
XMLString.AppendFormat("<{1}>{0}</{1}>", row[column].ToString(), column.ColumnName);
}
XMLString.AppendFormat("</RowData>");
}
XMLString.AppendFormat("</{0}>", table.TableName);
return XMLString.ToString();
}
2 - 私はConvertToXMLDataStringへのDataTableを渡すの最終結果は、きれいにフォーマットされたデータの1000行、すべての整数、10列
DataTable table = new DataTable("DataTable");
for(int i = 1; i < 11; i++){
table.Columns.Add(new DataColumn("Column" + i.ToString()));
}
int j = 0;
for (int i = 0; i < 1000; i++) {
DataRow newRow = table.NewRow();
for (int k = 0; k < table.Columns.Count; k++) {
newRow[k] = j++;
}
table.Rows.Add(newRow);
}
が含まれています簡単な例のデータテーブルを作成しました次に、そのXを処理するストアドプロシージャを作成 -
<DataTable>
<RowData>
<Column1>0</Column1>
<Column2>1</Column2>
<Column3>2</Column3>
<Column4>3</Column4>
<Column5>4</Column5>
<Column6>5</Column6>
<Column7>6</Column7>
<Column8>7</Column8>
<Column9>8</Column9>
<Column10>9</Column10>
</RowData>
<RowData>
<Column1>10</Column1>
<Column2>11</Column2>
<Column3>12</Column3>
<Column4>13</Column4>
<Column5>14</Column5>
<Column6>15</Column6>
<Column7>16</Column7>
<Column8>17</Column8>
<Column9>18</Column9>
<Column10>19</Column10>
</RowData>
</DataTable>
3:ストアドプロシージャに渡され、容易に選択することができるデータテーブルのXML表現MLデータ文字列を渡します。
CREATE PROCEDURE [dbo].[pr_Test_ConvertTable]
@TableData XML
AS
BEGIN
SET NOCOUNT ON
SET ANSI_NULLS ON
SET ARITHABORT ON
DECLARE @TempTable TABLE (
Column1 int, Column2 int, Column3 int, Column4 int, Column5 int,
Column6 int, Column7 int, Column8 int, Column9 int, Column10 int
)
INSERT INTO @TempTable (Column1, Column2, Column3, Column4, Column5, Column6, Column7, Column8, Column9, Column10)
SELECT XmlTable.Data.value('(./Column1)[1]','int'), XmlTable.Data.value('(./Column2)[1]','int'),
XmlTable.Data.value('(./Column3)[1]','int'), XmlTable.Data.value('(./Column4)[1]','int'),
XmlTable.Data.value('(./Column5)[1]','int'), XmlTable.Data.value('(./Column6)[1]','int'),
XmlTable.Data.value('(./Column7)[1]','int'), XmlTable.Data.value('(./Column8)[1]','int'),
XmlTable.Data.value('(./Column9)[1]','int'), XmlTable.Data.value('(./Column10)[1]','int')
FROM @TableData.nodes('//DataTable/RowData') AS XmlTable(Data)
SELECT * FROM @TempTable
END
GO
4 - 手順は@TableDataのXML変数を受け入れ、@TempTable呼ばれる新しく作成されたテーブル変数に挿入します。
最後に、適切なXMLパラメータを使用してデータベース呼び出しを作成します。通常と同じようにSPを呼び出し、パラメータとして使用してください。
cmd.Parameters.Add("@TableData", SqlDbType.Xml).Value = ConvertToXMLDataString(table);
ありがとうございます。それに応じて調整してデータを扱うことができるはずです。私は、通常、DataTableを渡すことが嫌い、ObjectやListを渡すことはあまりありませんが、この状況では、おそらくDataTableにデータがあります。
これが一度しか実行されていない、またはしばしばタイプのものではない場合、XMLを使用する便宜のために取ったパフォーマンスヒットは最小限です。これが多くのユーザーによって頻繁に行われる場合は、より効率的な方法を使用してください。
ああ、私は決して本当にセレクト*をしません。例のためだけに。これにしないでください。 –
- 1. データのバルク挿入にRavenDBを使用
- 2. VARBINARYをストアドプロシージャに渡す
- 3. ストアドプロシージャにデータテーブルを渡す
- 4. 配列をストアドプロシージャに渡す
- 5. SSIS:ストアドプロシージャにレコードセットを渡す
- 6. 可変数のパラメータをストアドプロシージャに渡す
- 7. IDの配列をストアドプロシージャに渡す
- 8. VBScript:null値のパラメータをストアドプロシージャに渡す?
- 9. ストアドプロシージャに負の値を渡す
- 10. 複数の値をストアドプロシージャに渡す
- 11. T-SQLのストアドプロシージャにカラムを渡す
- 12. 削除データは、挿入バルク文の
- 13. バルク非テーブル形式のExcelデータをデータベースにエクスポートする
- 14. SQL Server 2008のトリガからストアドプロシージャに一時データを渡す方法
- 15. ストアドプロシージャにパスを渡す方法は?
- 16. ストアドプロシージャにネットワークパスを渡す方法は?
- 17. リスト<string>をストアドプロシージャに渡す
- 18. PL/SQL:レキシカルパラメータをストアドプロシージャに渡す
- 19. リストをTSQL 2008ストアドプロシージャに渡す
- 20. EFストアドプロシージャにパラメータを渡す方法は?
- 21. SQLストアドプロシージャを "order by"に渡す
- 22. SSISストアドプロシージャにパラメータの配列を渡すSQLを実行するタスク
- 23. ajaxデータにストアドプロシージャを送信
- 24. execストアドプロシージャのパラメータを渡す方法
- 25. Zend_Db_Table_Rowsetにデータを渡して、各行のモデルを返す
- 26. ストアドプロシージャを実行した後のデータ型の指定方法は?
- 27. Laravelにデータを渡すタイプ移行時のビット/バイトタイプ
- 28. ストアドプロシージャに渡される動的パラメータ
- 29. Nullable <int>をF#のストアドプロシージャに渡すには?
- 30. は、バルクのRedis
SQL Serverを使用していますか?もしそうなら、どのバージョンのSQL Serverを使用していますか? –
1000はそれほど多くはありません - あなたは気にする必要がありますか?とにかく目立ったパフォーマンス上の問題が発生していないと、一度に1つずつ1000行が見つかるかもしれません。一度に1つずつ行うほうが簡単な場合は、最初に試してみて、何が起こるかを見てみましょう。 –