Sqlserver 2005 XMLを用いて一度に複数のレコードを更新する方法

2589 ワード

多くの人が知っていると思いますが、oracleでは、ストレージ・プロシージャにint[]などの配列が転送されます.つまり、複数のレコードがデータに転送され、一緒に更新されます.データベースの要求回数を減らす.
しかしSqlServerは?bulk Insertという多くの人が知っていて、私も知っていますが、残念ながら、私は使ったことがありません.データを導くときだけ考えますが、データを導くDTSのほうが便利ではないでしょうか.
手元の1つのプロジェクトには、いくつかの機能があり、毎回N(N<1000)レコードを更新する必要があり、記録は多くありませんが、毎回1つだけ更新し、insertを循環すると、各機能にはN回のデータベース要求が必要です.1000個の同時があれば、データベースはあなたのことをする以外に、他の仕事はしません.したがって、データベース要求を最小限に抑え、すべてのレコードを一度に更新する必要があります.
幸いなことに、SqlServerはXMLを利用する新しい機能を提供してくれました(2000はこの機能がないようです).
まず,ユーザがbookを更新するとともに,N個の章を更新する必要があるという需要を仮定する.
一般的な考え方は,まずbookを更新し,次いで章数をループし,データの章表をN回更新することである.皆さんはこの性能を見ることができます.
ではXMLで試してみましょう
XML更新によるストアド・プロシージャ
 
  
Create PROCEDURE UP_Book_Insert
(
@BookId INT,
@ChapterXml XML
)
AS
BEGIN
CREATE TABLE #table
(
ChapterId INT,
ChapterName VARCHAR(255),
Price INT
);
INSERT #table
SELECT *
FROM (
SELECT X.C.value('Id[1]', 'int') AS ChapterId,
X.C.value('Name[1]', 'varchar(255)') AS ChapterName,
X.C.value('Price[1]','int') AS Price
FROM @ChapterXml.nodes('Chapter') AS X(C) -- : X(C)
) t;
INSERT INTO tbChapter(BookId,ChapterId,ChapterName,Price)
SELECT @BookId,ChapterId,ChapterName,Price from #table;
END

実は、ストレージ・プロシージャでテンポラリ・テーブルを削除することができます.
そして実行してみましょう
ストアド・プロシージャの実行
 
  
exec UP_Book_Insert 10000,'268 268 100273 273 100275 275 100'

どうですか.いいですね.XMLフォーマットをストレージ・プロシージャで解析するだけです.
c#では、XMLフォーマットがDbTypeに転送されます.Stringタイプでいいです.
XML形式の文字列を生成するために関数をもう1つ書きます
XML形式の関数の生成
 
  
public static string FormatXmlInfo(List list)
{
if (list==null||list.Count<=0)
{
return String.Empty;
}
StringBuilder sb = new StringBuilder();
foreach (ChapterInfo info in list)
{
sb.AppendFormat("{0}{1}{2}", info.ChapterId, info.ChapterName, info.Price);
}
return sb.ToString();
}


はい、できました.
パフォーマンスは具体的にはどうですか.まだテストされていませんが、複数回データベースを要求したり、ストレージ・プロシージャで文字列をループ分割したりするよりも効率的です.