- PR -

ストアドプロシージャでデータベースを更新

1
投稿者投稿内容
未記入
会議室デビュー日: 2004/08/25
投稿数: 6
投稿日時: 2004-09-06 10:19
お世話になります。
VBもSQLも始めてまもないので、わからないことが多いので、
ご教授願いたく書き込みました。

ストアドプロシージャを使って、SQLサーバーのデータベースの
複数のテーブルからいくつかの項目を抽出し、1つのデータセット
を作成しました。次に、クライアント側で、データセットの更新を
行いました。
次の作業として、ストアドプロシージャを使って、データセットの
各項目をそれぞれのテーブルに戻し、データベースを更新したいです。
ですが、複数のテーブルから1つにまとめてしまったデータセットを
再び分解?して、テーブルに戻す方法がわかりません。この作業を
ストアドプロシージャで行いたいと思ってます。

初心者なもので、わかりずらい文章になってしまいましたが、なにか
ご存知でしたら、アドバイスお願いします。
nodera
大ベテラン
会議室デビュー日: 2003/09/08
投稿数: 200
投稿日時: 2004-09-06 14:23
INSERT、UPDATE、DELETEといったSQLステートメントは基本的に1つのテーブルにしか更新処理を行うことしかできません。複数のテーブルから取得した情報を、ひとつのDataSet(というよりDataTableですよね。結合クエリの結果を1つのDataTableに取り込んだという前提で話を進めます)に格納した場合、それに対する変更の更新処理は、未記入さんが考えているようにテーブルごとにばらして更新する必要があります。しかし、DataSet自身にはその情報がどのテーブルのどのフィールドから取得されたものであるかという情報をもっていません。ですから、ばらしの作業も、更新する先も製造者が意識して作る必要があります。
大体においてDataTableのフィールドには、それぞれのテーブルのキーになる情報を含めていると思いますので(なんとかIDとか)、そのキーを使用して、テーブル単位ごとに更新することになります。

さらに情報として記述しておくと、DataSetには複数のDataTableと1つのDataRelationを使って結合クエリーと同じような結果を得ることもできます。これだとDataTable=1つのテーブルとなるので、更新ロジックを簡素にできるという利点があります。(自分はDataRelationってあまり使ったことないでの、詳しいことは書けないんですが^^;)
未記入
会議室デビュー日: 2004/08/25
投稿数: 6
投稿日時: 2004-09-07 15:16
noderaさん、ご回答ありがとうございます。

>ばらしの作業も、更新する先も製造者が意識して作る必要があります。

この内容についてですが、DataAdapter1から3つのテーブルを結合し、
DataSet1を作成しました。しかしDataSet(DataTable)をばらして更新
する方法がわかりませんでした。

DataAdapter1の(なし)になっているUpdateCommandのCommandTextと
Connectionを変更してみましたが、うまくいきませんでした。
コードもいじってみましたが、どうしてもエラーが出てしまいます。

度々で申し訳ありませんが、よろしくお願いします。
nodera
大ベテラン
会議室デビュー日: 2003/09/08
投稿数: 200
投稿日時: 2004-09-07 19:01
こんにちは。
>どうしてもエラーが出てしまいます。
どのように変更して、どんなエラーが発生したのか状況を詳しく書いたほうが、答える側も答え易くなるので、今後はよろしくお願いします。

未記入さんがどのような方法をとったか分からないのでサンプルを記述します。
ただしエラー処理とかトランザクションとか端折って書くので、そのあたりは未記入さんのほうで付け加えてください。

まず次のようなテーブルがあると仮定します。
---------------------------------------
TableA
ID int ・・・キー
NAME varchar(50)

TableB
ID int ・・・キー
Amount int
---------------------------------------

この2つのテーブルを次のような結合クエリーで読み出すデータアダプタをウィザードで作成します。結合クエリーの場合、Update/Insert/Deleteといったコマンドは生成されません。たぶん未記入さんもウィザードで作成していると思います。また自分が試したテストコードでは、ストアドで作成にしました。
---------------------------------------
SELECT A.ID, A.NAME, B.Amount FROM TableA A INNER JOIN TableB B ON A.ID = B.ID
---------------------------------------
ついでにそのデータアダプタからデータセットも生成しておきます。
(下のサンプルコードでdataSet11がそれです)

続いて、更新用に次のようなストアドを用意します。
---------------------------------------
CREATE PROCEDURE dbo.UpdateTableAB
(
@ID int,
@NAME varchar(50),
@Amount int,
@OrgID int
)
AS
SET NOCOUNT ON

update TableA SET ID = @ID, [NAME] = @Name WHERE ID = @OrgID
update TableB SET ID = @ID, Amount = @Amount WHERE ID = @OrgID

RETURN
---------------------------------------
これは自分で作成です。通常キーを変更するようなことはないと思いますが、テストでキーも含めて更新するようにしてみました。(NAMEが[]で囲まれているのは予約語とかぶったから)
この部分がばらして更新という部分です。(ニュアンスがおかしいかもw)

で、実際のソース側。
---------------------------------------
// 更新コマンドの作成
OleDbCommand updateCommand = new OleDbCommand("UpdateTableAB");
updateCommand.CommandType = CommandType.StoredProcedure;
updateCommand.Connection = this.oleDbConnection1;
// パラメータ設定
OleDbParameterCollection pc = updateCommand.Parameters;
pc.Add("ID", System.Data.OleDb.OleDbType.Integer, 0, "ID");
pc.Add("NAME", System.Data.OleDb.OleDbType.VarChar, 50, "NAME");
pc.Add("Amount", System.Data.OleDb.OleDbType.Integer, 0, "Amount");
OleDbParameter param = pc.Add("OrgID", System.Data.OleDb.OleDbType.Integer, 0, "ID");
param.SourceVersion = DataRowVersion.Original;
this.oleDbDataAdapter1.UpdateCommand = updateCommand;
// データ読み込み
this.oleDbDataAdapter1.Fill(this.dataSet11);
// 変更
dataSet11.TableA[0].NAME = "変更後";
dataSet11.TableA[1].Amount = 100;
dataSet11.TableA[2].ID = 30;
dataSet11.TableA[2].NAME = "変更した";
dataSet11.TableA[2].Amount = 1000;
// 更新
this.oleDbDataAdapter1.Update(this.dataSet11);
---------------------------------------
コマンドの作成から、データの読み出し、データセットの変更、更新まで続けて記述しているので読みにくいのは許してください。また、TableAとTableBにはそれぞれ同一キーで3レコードずつ入っていると仮定しています。
データアダプタのUpdateメソッドを呼び出すと、引数で渡されたデータセットの変更行それぞれに対し、UpdateCommandで指定されたコマンドが実行されていきます。引数はコマンドパラメータで指定されているものです。4番目のパラメータには変更前のIDをセットするようにしました。

これで結合クエリーで取得されたDataSetに対する変更、更新するが可能となります。
コードも説明も端折りすぎかもしれませんが、それぞれのコードを紐解いて理解してみてください。
1

スキルアップ/キャリアアップ(JOB@IT)