
ご相談します。
SqlDataReaderで「sum」を取得する際、0件の判定がうまくできません。
該当0件にも拘らず、読み込みが行えた時のステップが実行されてしまい、「System.InvalidCastException: '指定されたキャストは有効ではありません。'」が発生します。
しかし、「Select」文に「group by」を付けると、正しく、問題の該当ステップが回避されます。すでに、「where」句で対象レコードを絞り込んでいるため、「group by」をする必要はないため、「group by」は付けたくありません。
ネット検索しましたが、「group by」を付けなければならない話は見つけられませんでした。それとも、「sum」関数を使う場合の制約か何かがあるのでしょうか?
エラー発生:
String str_zan_Az = "select sum(UkeZan * Tnk * Rate / KeiQty) as AzKin_total from zan" +
" where ((ActNo = @ActNo_Az) and (Class = '00'))";
SqlCommand cmd_zan_Az = new SqlCommand(str_zan_Az, conn_JIP_HULFT_Dev);
SqlParameter parm_zan_Az = new SqlParameter("@ActNo_Az", SqlDbType.Char, 7);
cmd_zan_Az.Parameters.Add(parm_zan_Az);
cmd_zan_Az.Parameters["@ActNo_Az"].Value = reader_kyaku["ActNo"] as string;
using (SqlDataReader reader_zan_Az = cmd_zan_Az.ExecuteReader())
{
while (reader_zan_Az.Read() == true)
{
local_Azkin_total = local_Azkin_total + (decimal)reader_zan_Az["AzKin_total"]; <--- ここで、上記エラーが発生します
}
}
エラー発生しない:
String str_zan_Az = "select sum(UkeZan * Tnk * Rate / KeiQty) as AzKin_total from zan" +
" where ((ActNo = @ActNo_Az) and (Class = '00'))" +
" group by ActNo, Class"; <-- 「group by」を付けると、上記エラーが発生しません
SqlCommand cmd_zan_Az = new SqlCommand(str_zan_Az, conn_JIP_HULFT_Dev);
SqlParameter parm_zan_Az = new SqlParameter("@ActNo_Az", SqlDbType.Char, 7);
cmd_zan_Az.Parameters.Add(parm_zan_Az);
cmd_zan_Az.Parameters["@ActNo_Az"].Value = reader_kyaku["ActNo"] as string;
using (SqlDataReader reader_zan_Az = cmd_zan_Az.ExecuteReader())
{
while (reader_zan_Az.Read() == true)
{
local_Azkin_total = local_Azkin_total + (decimal)reader_zan_Az["AzKin_total"];
}
}
よろしくお願いします。
VisualStudio
Microsoft Visual Studio Professional 2017 (2)
Version 15.5.7
VisualStudio.15.Release/15.5.7+27130.2036
Microsoft .NET Framework
Version 4.7.03056
C#
Visual C# 2017 00370-20007-72734-AA238
Microsoft Visual C# 2017
SQL Server
Microsoft SQL Server Express (64-bit)
13.0.4206.0
Microsoft Windows NT 6.3 (17134)
PC
Microsoft Windows [Version 10.0.17134.165]
No.4ベストアンサー
- 回答日時:
SQL Server Management Studio はインストールしてありますか?
あるのなら、各SQLでどんな結果が返るか確認するのがいいかと。
groupの無い方は、whereで該当する0件の集計結果として、nullの行を返します。
ある方は、グループ毎に集計してwhereで該当するグループを返す(ように見える)ので、0行返します。
countで行数も数えて先に判定する、isnullで0にしてしまう、decimalにキャストするまえにnullかどうか確認する、などがかんがえられます。
ただ、手元で実行プランを確認したところ、groupの有無で、プランもパフォーマンスも違いはほとんどありませんでした。
kmeeさん
SQL Server Management Studioはインストールしてありましたので確認しました。(不慣れで、この様な使い方を思いつきませんでした)
「group by」しない方は、sum項目「MRF_total」が「NULL」にも拘らず、「(1行処理されました)」となっていました。このため、「while (reader_zan_MRF.Read() == true)」が成り立ってしまったと考えました。
それに対し、「group by」する方は、「(0行処理されました)」となるため、「while (reader_zan_MRF.Read() == true)」が成り立たなかったと考えました。
そして、『「group by」しない方は、1行処理され、NULL値が返されたが、
「group by」する方の「MRF_total」の空欄は、1行も処理されていない為、NULL値すら返されていない。』という事でしょうか?
丁寧な調査と優しい回答をありがとうございます。
大今
No.2
- 回答日時:
>(decimal)reader_zan_Az["AzKin_total"];
詳しく見てないけど、NULLが返っているとかじゃないですかね?
慎重にキャストする、何かが足りない気がする。
回答をありがとうございます。
はい、おそらく計算項目がNULLのために、エラーになっていると思います。
そのため、「while (reader_zan_Az.Read() == true)」の中に計算式を配置して、読み込めた時のみ計算しようとしているのですが、該当なしの時にも「while (reader_zan_Az.Read() == true)」の中に入ってきてしまいます。
ところが不思議なことに、「group by」を付けると、該当なしの時に「while (reader_zan_Az.Read() == true)」の中に入って来ません。(「該当なし」が正しく認識されているようです)
しかし、本来(この件を除いては)「group by」を付ける必要性はないと考えているため、出来れば、「group by」を付けたくないのです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
.NET SqlDataReader のレコード有無判定
Visual Basic(VBA)
-
SQL、2つのテーブルで条件一致したものだけdeleteする方法は?
Oracle
-
INSERT文でフィールドの1つだけを他のテーブルから取ってきた値を入れたい
その他(データベース)
-
-
4
Visual Basic.NETの、Form 間での引数の引渡し方法を教えてください。
Visual Basic(VBA)
-
5
ExecuteNonQueryメソッドの戻り値
その他(プログラミング・Web制作)
-
6
IPアドレスだとPingが通るのに、PC名だとPingが通らない
マルウェア・コンピュータウイルス
-
7
VBのReturnの使い方
Visual Basic(VBA)
-
8
【DB】同じトランザクション内でupdateとselectをしたときの結果値
その他(データベース)
-
9
VB.NETで DataRow()を利用して、値からコードを取得したい。
Visual Basic(VBA)
-
10
値を返さないコード パス
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
bcpで抽出した結果をエクセルに...
-
Transact-SQLでテキストファイ...
-
20人程度が一度に使うデータベ...
-
SQL SERVERのドメインを変更する
-
SQLServerへのOpen命令でのエラー
-
SQLで同じDBに対し2つのコネク...
-
sqlで文字列を最後に追加したい
-
Access2000環境に対応するMid関...
-
SQL Loaderを使いたい
-
SQLサーバー接続 特定のPCがWin...
-
SQLサーバー接続について
-
PostgreSqlでFunctionの作成に...
-
既定のインスタンスと名前付き...
-
GROUP BYでエラーが発生
-
ACCESSからのODBC接続のみ応答...
-
Oracle 8i コンマ(,)を含むデ...
-
ユーザー定義関数内でのsp_exec...
-
今、何のストアドを実行してい...
-
SQLのエラー(~付近に不適切な...
-
SQL ServerにTCP/IPで接続出来ない
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
SqlDataReaderでの0件判定
-
Transact-SQLでテキストファイ...
-
bcpで抽出した結果をエクセルに...
-
SQL Server 2005 データベース...
-
Accessプロジェクト ストアド...
-
AccessからExcelへパラメータで...
-
SQLのエラー(~付近に不適切な...
-
20人程度が一度に使うデータベ...
-
PostgreSqlでFunctionの作成に...
-
Excel-VBAの「しばらくお待ちく...
-
Oracle 8i コンマ(,)を含むデ...
-
GROUP BYでエラーが発生
-
SQL Loaderを使いたい
-
SQLサーバー接続 特定のPCがWin...
-
ACCESSからのODBC接続のみ応答...
-
99bb.com のライセンスバック...
-
ACCESS ADOでupdateが効かない
-
SQLCMDにて教えていただきたい...
-
既定のインスタンスと名前付き...
-
AccessのDAO.ExecuteとDoCmd.Ru...
おすすめ情報
kmeeさん
お礼に書き漏らしましたので、こちらで補足します。
今回の対応、本来は、計算前に、NULLやcount数を確認するのでしょうが、
上記の確認を行わず、代わりに、Selectに「group by」を付けるというワークアラウンドもありという事ですね。