Road to DBD

Road to DBD

PR

×

カレンダー

バックナンバー

2026.05
2026.04
2026.03
2026.02
2026.01

キーワードサーチ

▼キーワード検索

プロフィール

ジャムシード

ジャムシード

コメント新着

mayggW@ продвижение раскрутка сайта договор Заказать seo поисковую оптимизацию сайт…
通りすがりプログラマー@ Re:複数テーブルによるUPDATE(02/11) 随分前の記事にコメント失礼します。 rown…
ワンコ0995 @ Re:包含データベース(06/02) ((データベース)データベース,)デー…
しぐしぐ@ Re:TOP 100 PERCENT(05/08) お世話になっております。 最近、旧システ…
ハニー@ Re:INSTEAD OFトリガの限界(07/16) 1SQLでやらずに変数に入れればいいじゃん
2009.05.09
XML
カテゴリ: DB-TransactSQL
「インサイド SQL Server 2005」シリーズは4冊ある。
・ストレージエンジン編
・クエリチューニング&最適化編
・T-SQLクエリ編
・T-SQLプログラミング編
しかし、邦訳が出版されたのは上の2冊だけで、あとの2冊は結局邦訳されなかった。

そこで「T-SQLプログラミング編」を原書で購入して読んでいた。やはりすごい本だ。

この中で、「ストアドプロシージャのパラメータをXMLで受け渡すこと」について言及されていてハッとした。
SQL Server2008ではテーブル値パラメータがサポートされたが、それまではストアドプロシージャにはスカラー形式でのパラメータしか渡すことができなかった。実際にフロントエンドにAccessや.NETのグリッドなどを使っていると、複数セットのデータをパラメータとして受け渡したいことがよく出てくる。


ワンセットであれば、以下のようなパラメータでもいい。
EXEC sp_UpdateInfo @CustomerID,@TradeID,@Date,@ProdCD,@Amount

しかし、パラメータの数が多かったり、複数セットの場合はバラバラのパラメータを用意していてはキリがないので、パラメータは1つにしてデリミタで区切って渡したりする。
EXEC sp_UpdateInfo @PARM
この@PARMに「12345678,12,2008/12/31,101,25!222345678,12,2009/01/04,102,20」などという値をセットすることになるわけだ。

一方、ストアドプロシージャ側でもこれを区切ってテーブルに戻すために、「デリミタ区切りの文字列をテーブル化する」ようなテーブル関数を予め準備しておく必要がある。仮にこれをsf_TOTABLEとすると、テーブル化するのには意外と手間がかかる。

DECLARE D_CUR CURSOR LOCAL FOR
 SELECT ITEM FROM sf_TOTABLE(@PARM,'!')
ORDER BY SEQ
OPEN D_CUR
FETCH NEXT FROM D_CUR INTO @ITEM

BEGIN
 INSERT INTO #TABLE
 SELECT
 MAX(CASE WHEN SEQ=1 THEN ITEM END) CustomerID,
 MAX(CASE WHEN SEQ=2 THEN ITEM END) TradeID,

 MAX(CASE WHEN SEQ=4 THEN ITEM END) ProdCD,
 MAX(CASE WHEN SEQ=5 THEN ITEM END) Amount
 FROM sf_TOTABLE(@ITEM,',')

 FETCH NEXT FROM D_CUR INTO @ITEM
END
CLOSE D_CUR
DEALLOCATE D_CUR

実際にこの方法で受け渡しを行ったりしているのだが、やはりスマートとはいい難い。二重のデリミタに加えて、「何カラム名が何の項目か」も分からない状態で受け渡しをすることになる。

では、XMLをパラメータにするとどうなるか。
パラメータの内容は以下の形になるだろう。
<Parameters>
<CustomerID>12345678</CustomerID>
<TradeID>12</TradeID>
<Date>2008/12/31</Date>
<ProdCD>101</ProdCD>
<Amount>25</Amount>
</Parameters>
<Parameters>
<CustomerID>22345678</CustomerID>
<TradeID>13</TradeID>
<Date>2009/01/04</Date>
<ProdCD>102</ProdCD>
<Amount>20</Amount>
</Parameters>

EXEC sp_UpdateInfo @PARM
受け取ったストアドプロシージャ側では@PARMという1つのパラメータを受け取るにも関わらず、それぞれの項目が何かも把握できる。
そしてテーブル化にはテーブル関数もカーソルも必要がない。

INSERT INTO #TABLE
SELECT
x.c.value('(./CustomerID/text())[1]','varchar(max)') CustomerID,
x.c.value('(./TradeID/text())[1]','varchar(max)') TradeID,
x.c.value('(./Date/text())[1]','varchar(max)') Date,
x.c.value('(./ProdCD/text())[1]','varchar(max)') ProdCD,
x.c.value('(./Amount/text())[1]','varchar(max)') Amount
FROM @XML.nodes('/Parameters') AS x(c)

SQL Server 2005限定とは言え、これは悪くない方法だと思う。





お気に入りの記事を「いいね!」で応援しよう

最終更新日  2009.05.10 05:02:22
コメント(0) | コメントを書く
[DB-TransactSQL] カテゴリの最新記事


■コメント

お名前
タイトル
メッセージ
画像認証
上の画像で表示されている数字を入力して下さい。


利用規約 に同意してコメントを
※コメントに関するよくある質問は、 こちら をご確認ください。


【毎日開催】
15記事にいいね!で1ポイント
10秒滞在
いいね! -- / --
おめでとうございます!
ミッションを達成しました。
※「ポイントを獲得する」ボタンを押すと広告が表示されます。
x
X

© Rakuten Group, Inc.
Mobilize your Site
スマートフォン版を閲覧 | PC版を閲覧
Share by: