- - PR -
DataGridでオーバフローが発生する
1
| 投稿者 | 投稿内容 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-01-20 11:02
こんにちは。ゆきおといいます。
Oracleのデータディクショナリを検索するシステムをC#で作成しています。 DataGridに結果を格納させているのですが、特定のSQL文を発行するとオーバー フローが発生しDataGridに結果が格納されません。 【環境】 OS:Windows2000 SP4 Oracle:Oracle9i Release 9.2.0 トライアル版 言語:Visual C#.NET + Oracle Data Provider for .NET(ODP.NET) .Net Framework v1.1 【ソースコード】 class ConnectOracleDB { [STAThread] static void Main() { Application.Run(new Form1()); } } private void button1_Click(object sender, System.EventArgs e) { // @Oracleに接続 // Create the connect object OracleConnection con = new OracleConnection(); con.ConnectionString = "User Id=xxxx;Password=pppp; Data Source=dddd; DBA Privilege=SYSDBA;"; // Instantiate OracleDataAdapter to create DataSet OracleDataAdapter myAdapter = new OracleDataAdapter(); // Fetch Product Details myAdapter.SelectCommand = new OracleCommand ("SELECT namespace,gethitratio FROM v$librarycache",con); // DataTable myDataTable = new DataTable(); myAdapter.Fill(myDataTable); // ADataGridに結果格納 dataGrid1.SetDataBinding(myDataTable); } 【上記APを実行するとエラーとなる症状】 1.画面でボタン(button1)をクリックすると以下のメッセージが表示される。 「演算操作の結果オーバーフローが発生しました。」 2.DataGridにはNullが表示される 【問題となるSQL文】 SELECT namespace,gethitratio FROM v$librarycache 【SQL/Plusの結果】 NAMESPACE GETHITRATIO --------------- ----------- SQL AREA .992936844 ・・・・ A TABLE/PROCEDURE .990651713 BODY .947368421 TRIGGER .966666667 INDEX .997985515 CLUSTER .959302326 OBJECT 1 PIPE 1 JAVA SOURCE 1 JAVA RESOURCE 1 JAVA DATA 1 【質問事項】 SQL/Plusの結果よりSQL文に間違いはないと考えています。また他の SQL文を発行すると(例:SELECT * FROM v$database)正常に結果が表 示されることよりDataGridに原因があると自分では考えています。 具体的には「結果」よりGETHITRATIO列の小数点(1以外の結果) がDataGridでは表示できないのかなと考えています。 質問ですが ・オーバフローの原因は上記であっているんでしょうか? ・またこのようなオーバーフローする事象はDataGridでは よくあるのでしょうか? どなたかすいませんが教えていただけると幸いです。 ※長文で申し訳ありません。 | ||||||||
|
投稿日時: 2004-01-20 11:38
>// ADataGridに結果格納
> dataGrid1.SetDataBinding(myDataTable); この行をコメントアウトにしたらどうなります? >myAdapter.Fill(myDataTable); こっちでエラーがでてるかもしれないので | ||||||||
|
投稿日時: 2004-01-20 12:03
「OCI-22053:オーバーフロー・エラー」でしょうか?
Adapter.Fillで発生しています。 | ||||||||
|
投稿日時: 2004-01-20 12:58
・OracleNumber 構造体
http://www.microsoft.com/japan/msdn/library/ja/cpref/html/frlrfsystemdataoracleclientoraclenumberclasstopic.asp?frame=true この情報が参考にならないでしょうか? 外していたらすいません。 | ||||||||
|
投稿日時: 2004-01-20 14:33
ゆうじゅんさんこんにちは。返信ありがとうございます。 コメントアウトしてデバッグモードで実行してみました。 ご指摘通りmyAdapter.Fill(myDataTable); で例外が発生しました。 メッセージを記します。 ↓----------------------------------------------------------------------------- 'System.OverflowException'のハンドルされていない例外が oracle.dataaccess.dll で 発生しました。 追加情報:演算操作の結果オーバフローが発生しました。 ↑----------------------------------------------------------------------------- これでいくとdataGridが原因ではなくてmyAdapter.Fillに原因がありそうです。 ますますわからなくなってきたような。
Jittaさんこんにちは。続けざまの返信で失礼します。 上記のOCIのエラーメッセージは表示されませんでした。ただAdapter.Fillが原因のようですね。ただどうすればいいのか考え中です。 (OracleDataAdapter myAdapterとAdapterは一緒と考えていいのでしょうか?) | ||||||||
|
投稿日時: 2004-01-20 16:21
NAL-6295さん。こんにちは。
OracleNumber 構造体参照させていただきました。 大きなデータを取得する場合getOracleNumberを使用するようですね。 OracleDataReader reader = cmd.ExecuteReader(); reader.GetOracleNumber(1); 情報参考になります。原因としては今のところ myAdapter.Fill(myDataTable); で発生してるようなので回避策をいろいろと探します。情報ありがとうございます。 | ||||||||
|
投稿日時: 2004-01-20 16:35
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpguide/html/cpconmappingnetdataproviderdatatypestonetframeworkdatatypes.asp の下の方の説明によると・・・ FillErrorイベントで回避できるようです。 で、回避の仕方は http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpguide/html/cpconaddingremovingadonetproviderevents.asp のFillErrorの項に掲載されています。 以上、よろしくお願いします。 | ||||||||
|
投稿日時: 2004-01-21 11:33
NAL-6295さんこんにちは。
FillErrorイベントを作成して、実行したらエラーは回避できるようになりました。 以下を追加してみました。 @イベントハンドラの作成 myAdapter.FillError += new FillErrorEventHandler(FillError); Aエラー処理のメソッド作成 protected static void FillError(object sender, FillErrorEventArgs args) 最後にソースコードを記しますが、処理としてはFillを実行した後にオーバフローが発生するとイベントを発生させ、メソッド「FillError」を実行させます。FillErrorの中でオーバーフローが発生した列に対し、「null」文字列を埋め込みます。今回はサンプルに掲示されたイメージで動作させています。
上記記事から考えると、Oracleのデータ型と.NET Framework 型での相違に問題がありそうなのでオーバフローの発生した列に対して個別に「reader.GetOracleNumber(1) 」を発行し@個別に列の値を取得、ADataTableにデータ格納、BDataGridに表示といった処理が必要なのかなという気がします。@〜Bについては時間がかかると思いますが、挑戦しようと考えています。 NAL-6295さん貴重な情報どうもありがとうございます。また返信していただいた方にも本問題に取り組む上で大変助かりました。 【現ソースコード】 private void button1_Click(object sender, System.EventArgs e) { // Oracleに接続 // Create the connect object string connectionString = "User Id=sys;Password=sys; Data Source=test; DBA Privilege=SYSDBA;"; con = new OracleConnection(connectionString); con.Open(); string cmdQuery = "SELECT namespace,gethitratio FROM v$librarycache"; // Instantiate OracleDataAdapter to create DataSet myAdapter = new OracleDataAdapter(); *** 追加@ イベントハンドラの作成 *** myAdapter.FillError += new FillErrorEventHandler(FillError); // Fetch Product Details myAdapter.SelectCommand = new OracleCommand(cmdQuery ,con); // DataTable方式 myDataTable = new DataTable(); myAdapter.Fill(myDataTable); // DataGridに結果格納 this.dataGrid1.SetDataBinding(myDataTable,""); } *** 追加A *** protected static void FillError(object sender, FillErrorEventArgs args) { if (args.Errors.GetType() == typeof(System.OverflowException)) { // Code to handle precision loss. //Add a row to table using the values from the first two columns. DataRow myRow = args.DataTable.Rows.Add(new object[] {args.Value[0],DBNull.Value}); //Set the RowError containing the value for the third column. //args.RowError = "OverflowException Encountered. Value from data source: " + args.Values[1]; args.Continue = true; } | ||||||||
1
