- PR -

Web サービスにおけるDBの更新処理

投稿者投稿内容
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-01-09 14:33
引用:

Mickyさんの書き込み (2004-01-09 14:22) より:

しかし、XMLでのDataSetではこれらの情報はなくなってしまうので
更新の成功/失敗の情報を更新レコード分、付加してやらなければ
ならない事になります。
更にこの情報から「追加、変更、削除」それぞれの処理に対応する
エラー処理、元々持っていたDataSetとの整合性を取る事等、
処理が煩雑になるような気がしています。


 確認していませんが、そうですか?Addedなどの情報を持っていることは確認していますが。いや、エラー情報もシリアライズされていたように思います…よ?

 また、DataAdapter.Updateで例外が発生した場合は、その行で更新が止まりますから、複数のエラーデータが混ざっているという状況にはならないと思います。その1行はcatchブロックで走査して(エラー行を取る、というメソッドがあった?)メッセージを、私はEXCEPTIONという表に入れて、クライアントに返していました。クライアントはまずException表があるかどうかを調べ、例外が発生したかどうかを確認する、と。
Micky
大ベテラン
会議室デビュー日: 2002/09/04
投稿数: 137
投稿日時: 2004-01-09 15:05
引用:

Jittaさんの書き込み (2004-01-09 14:33) より:
 確認していませんが、そうですか?Addedなどの情報を持っていることは確認していますが。いや、エラー情報もシリアライズされていたように思います…よ?



実際に中身を見てみたのですが、それらしい物はありませんでした。
もう一度確認してみます。

引用:

 また、DataAdapter.Updateで例外が発生した場合は、その行で更新が止まりますから、複数のエラーデータが混ざっているという状況にはならないと思います。



ごめんなさい、これは書き方が悪かったです。
エラーが複数あると言うことではなくて、
更新OK複数、エラーがひとつとの混在と言うことです。

自分もエラー情報を表にすると言うのは考えたんです。

例えば、最初に更新したレコードが5個あるとします。

3行目と5行目がエラーになるとします。
最初のUpdateでは、1、2行目は正常更新終了して
3行目でエラーになるからここで止まります。

クライアント側では、1、2は成功して3は失敗したと言う
情報に基づき、1,2のRowStateをUnchangeに3に付いては
失敗した後の再読込後編集をして再度Updateに送ります。

今度対象になるのは3行目からで同じ事を行えばいける

とも考えたのですがここでの問題はやはり
行ごとの成功/失敗の情報の受け取り方ですね。
それと、これを何回も繰り返すより一行ずつの方が
確実かな?と思ったんです。

「DataSetを返すときに情報用カラムを付加して
受け取ったクライアントでカラムを削除する」
なんてのも考えたのですが、エラー情報も
シリアライズ化されてれば問題ないわけですね。

追記:
DiffGram形式と言うのがキーワードの様ですね。
確かにhasErrorという属性がありました。
以前、更新されたDataSetをクライアント側で
受け取って見た所ではエラー情報はセットされて
なかったんです。

追記2:
更新でエラーになった行を含むDataSetをWebServiceの
返り値としたのですが、エラーになってしまいました。

_message "XML ドキュメント (1,2558) でエラーが発生しました。" string
_innerException {"オブジェクト参照がオブジェクト インスタンスに設定されていません。" } System.Exception

以前はこんなエラーにはならなかったように思うのですが・・・(T_T)

再調査含めて進めてみます。

[ メッセージ編集済み 編集者: Micky 編集日時 2004-01-09 15:23 ]

[ メッセージ編集済み 編集者: Micky 編集日時 2004-01-09 17:38 ]
Os_
ベテラン
会議室デビュー日: 2003/04/16
投稿数: 77
投稿日時: 2004-01-10 12:56
おさです
引用:

Mickyさんの書き込み (2004-01-09 14:22) より:

更新された複数のレコードで
エラーが発生する可能性があり、
その対応処理についてよい方法が見つからないからです。

対象となる更新済みDataSetのUpdateメソッドを使用するとUpdateの結果をDataSetの
当該DataRowに設定してくれますよね。
・・[省略]・・
しかし、XMLでのDataSetではこれらの情報はなくなってしまうので
更新の成功/失敗の情報を更新レコード分、付加してやらなければ
ならない事になります。
更にこの情報から「追加、変更、削除」それぞれの処理に対応する
エラー処理、元々持っていたDataSetとの整合性を取る事等、
処理が煩雑になるような気がしています。



XMLでのDataSetではこれらの情報はなくなってしまうことはないと思いますが。
Update後のDataSetを戻すことで、エラーデータを含めたデータが利用できます。

但し、更新分を抽出したDataSetdeでUpdateしている場合は、当然のことながら
抽出元のDataSetへ結果を反映する必要があると思いますが。

また、元々持っていたDataSetとの整合性を取る事は、DataSet.Merge()メソッドで
エラーデータを含めて1コマンドで反映できるかと思いますが。

また、複数レコードの更新エラーの件ですが、エラーとしてはどの様な内容になりますか?
具体的にしていただければ対応方法もあるかと思いますが。
Micky
大ベテラン
会議室デビュー日: 2002/09/04
投稿数: 137
投稿日時: 2004-01-13 10:26
Mickyです。

おささんこんにちは!
&ありがとうございます。

エラー情報が付加されたDataSetが使用できるとの
情報を頂いたので、そっちの方向で作成していました。
(以前自分で試した時はエラー情報がなくなっている様だったので、
エラー情報を含んだDataSetは返せないと思い込んでいました)

想定しているエラーとは
・追加時の重複エラー
・更新、削除時の同時実行エラー
・その他エラー
なのですが、

追加時重複エラー(SqlException)が発生すると
−−−−−−−−−−−−−−−−−−
_message "XML ドキュメント (1,2558) でエラーが発生しました。" string
_innerException {"オブジェクト参照がオブジェクト インスタンスに設定されていません。" } System.Exception
−−−−−−−−−−−−−−−−−−
となってしまいます。
又、同時実行エラーを起こそうと一度読み込んだ後
SQL ServeEnterPriseManagerから更新して、
アプリから再度更新しても同時実行違反にならなかったり…

教えて頂いた、
「エラー情報を含んだDataSetの使用」

「Mergeを利用した元DataSetへの反映」

の所へ行く前で躓いてしまっているんです
引き続き調査してみます。
Os_
ベテラン
会議室デビュー日: 2003/04/16
投稿数: 77
投稿日時: 2004-01-13 13:34
おさです。

引用:

想定しているエラーとは
・追加時の重複エラー
・更新、削除時の同時実行エラー
・その他エラー
なのですが、



同時実行エラーが何をさすのかハッキリしませんが、
(SQLServeの場合、同時実行はありえない?)
更新予定のデータとDBのデータとの差異によるエラーであるならば、
DB更新の頻度にもよりますが、サーバーとのやり取りを何度も繰り返す必要はなく、
登録時のエラー(差異)が確認された時点で、DBの最新データを再読込みし、
現在クライアントにあるDataSetにマージすることで解消することは可能かと
思われますが、いかがですか?

また、このマージの終了後、差異のある部分を更新データとして再度登録することが
可能かと思います。
Micky
大ベテラン
会議室デビュー日: 2002/09/04
投稿数: 137
投稿日時: 2004-01-13 14:09
Mickyでございます。

引用:

Os_さんの書き込み (2004-01-13 13:34) より:
おさです。

DB更新の頻度にもよりますが、サーバーとのやり取りを何度も繰り返す必要はなく、
登録時のエラー(差異)が確認された時点で、DBの最新データを再読込みし、
現在クライアントにあるDataSetにマージすることで解消することは可能かと
思われますが、いかがですか?




えっと、繰り返しになっちゃって申し訳ないのですが…

最初に書き込みした時の「1」のやり方が基本でそれでやろうとしていました。
その時はMerge等を使った具体的な方法までは考えてませんでした。

みなさんの意見もその様な方向だったので、それでやり始めたのですが、
WebServiceの呼び元で帰ってきたDataSetにエラー情報が
入ってなかったのでエラー情報を取れないモノだと思い込み、
「1レコードずつ何度もやり取りする方法」に傾いたのですが、
その後やはりエラー情報は取得できると教えて頂いたので
その時点から本来の「1」の方法で作成しています。

ですので、おささんの仰られている事は一応理解していますし
なんの依存もありません。

所が現在は、相変わらずWebServiceの呼び元で
DataSetのエラー情報が取得できない事と、
二重登録エラーの時はSystemException
になってしまう事で悩んでいる状態なんです。
(それが、ここ何回かの書込みの内容です)

ややこしくなって申し訳ありませんm(__)m

Os_
ベテラン
会議室デビュー日: 2003/04/16
投稿数: 77
投稿日時: 2004-01-13 15:30
おさです。
失礼しました。

問題の件ですが、以下の2点に切り分けてよろしいですか?
1:WebServiceの呼び元でDataSetのエラー情報が取得できない
2:二重登録エラーの時はSystemExceptionになってしまう

1について確認ですが、WebService側で正しく設定されているRowErrorが
呼び出し元で取得できないということですか?
これはどの様にコーディングされているか確認が必要です。

2については、エラー発生時のDataSetの内容をWebService側で確認されてますか?、シリアライズできない項目がふくまれている可能性はありませんか?

不十分な内容ですみません。
Micky
大ベテラン
会議室デビュー日: 2002/09/04
投稿数: 137
投稿日時: 2004-01-13 17:21
Mickyでございます。

おささん、すっかりお付き合いいただいてしまって感謝しております。

問題を単純にする為にMSDNの
「XML Web サービスからの DataSet の使用」
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003APR.1041/cpguide/html/cpconconsumingdatasetfromwebservice.htm
のサンプルをほぼそのまま使用することにしました。

WebService側は適宜SQLServerへのコネクション、DataAdapterを自動作成し

//// 取得用WebMethod ///
public DataSet GetCustomers()
{
DataSet ds = new DataSet();

sqlDataAdapter1.Fill(ds );

return ds;
}

///更新用WebMethod///
public DataSet UpdateCustomers(DataSet custDS)
{
SqlDataAdapter custDA = sqlDataAdapter1;
try
{
sqlDataAdapter1.Update(custDS, "Customers");
}
catch( Exception ex )
{ ///とりあえず全ての例外をスルー
}

return custDS;
}

クライアント側はWinAppliとして、DataGridをひとつ、
「更新」ボタンをひとつ貼り付けて、取得したデータを一覧表示

/// 更新ボタンクリック ///
private void button1_Click(object sender, System.EventArgs e)
{
Service1 webService = new WinAppli.localhost.Service1();

DataSet ds = webService.UpdateCustomers( m_ds.GetChanges() );
}

としました。
これでDataGridから「すでにあるKeyのデータ」を追加して動作させると。
XMLの内容は
- <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
- <NewDataSet>
- <Customers diffgr:id="Customers1" msdata:rowOrder="0" diffgr:hasChanges="inserted" diffgr:hasErrors="true">
<CustomerID>Micky</CustomerID>
<CompanyName>Micky Corp</CompanyName>
<ContactName>micky</ContactName>
</Customers>
</NewDataSet>
- <diffgr:errors>
<Customers diffgr:id="Customers1" diffgr:Error="PRIMARY KEY 違反、制約 'PK_Customers': オブジェクト 'Customers' には重複したキーは挿入できません。" />
</diffgr:errors>
</diffgr:diffgram>

となり、確かにXMLにエラーデータが設定されています。
しかし、UpdateCustomersメソッドのretern文でエラーになってしまう。
("XML ドキュメント (1,xxxx) でエラーが発生しました。")
と言うのが現在の現象です。
この単純なプログラムで実行すると、「更新時エラー」も同様のエラーに
なってしまいます。

エラー情報を含んだDataSetを返す場合はなにか設定があるのか?
はたまた、環境に左右される要素があるのか?

と、悩んでいる最中です

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