• 締切済み

SQLについて教えてください。

お世話になります。 ORACLE SQLについて質問させて下さい。 ACCESS2003より以下のようなSQLを発行しています。 SELECT A.商品CD, A.区分, SUM(A.数量) AS 受数量, SUM(A.金額) AS 受金額 FROM テーブル1 A INNER JOIN テーブル2 B ON SUBSTR(A.商品CD,1,13) = B.商品コード WHERE A.年 = 2008 AND A.月 = 03 AND B.区分 = '51' GROUP BY CUBE(A.商品CD, A.区分) ORDER BY A.商品CD, A.区分 集計のSQLです。 SQLは正しいと思うのですが、実行結果が返ってきません。0件です。 調べていたところ、SQLを発行した後のレコードカウントに 「実行時エラー '-2147467259' データプロバイダまたはほかのサービスがE_FAIL状態を返しました。」 とあり、件数が0件(SQL自体動いていない?)でした。 SQL自体は開発ツールとして使用している、「オブジェクトブラウザ」のSQL発行機能にて実際に動かしてデータも正しく抽出されることは確認してるいるのですが。。 他にネットで調査したところ、抽出件数が多すぎると上記のようなエラーが起こる?みたいな事も書いてありました。 しかし、結果の件数はそんなに多くはないのです。(200レコードくらい。) なぜ起こるか、どうすればいいか、が良く分かりません。。。 解決策、回避策がありましたら教えていただきたいと思います。 SQLを発行するサブルーチンも記載しておきます。 ↓↓↓ Public Function cmn_DoSelectSql(ByVal pstrSql As String, pstrData() As String) As Long Dim lngErrNum As Long 'エラー値 Dim strErrMsg As String 'エラーメッセージ Dim adoRs As ADODB.Recordset 'レコードセット Dim lngColCnt As Long '最大レコード数 Dim lngRowCnt As Long '最大フィールド数 Dim objField() As Object Dim lngCol As Long 'レコードカウントアップ用 Dim lngRow As Long 'フィールドカウントアップ用 On Error Resume Next cmn_DoSelectSql = 0 '変数初期化 g_lngOraRecCnt = 0 'パラメータチェック If pstrSql = "" Then Call cmn_ErrMsgDsp("-", "パラメータ異常が発生しました。") cmn_DoSelectSql = -9 Exit Function End If If (g_adoCon Is Nothing) Then Call cmn_ErrMsgDsp("-", "パラメータ異常が発生しました。") cmn_DoSelectSql = -9 Exit Function End If Set adoRs = New ADODB.Recordset adoRs.CursorLocation = adUseClient 'SQL実行 adoRs.Open pstrSql, g_adoCon, adOpenStatic, , adCmdText 'エラーセット lngErrNum = Err strErrMsg = Error(Err) 'エラーメッセージ表示 If (lngErrNum <> 0) Then Select Case lngErrNum '排他エラー Case 54: cmn_DoSelectSql = -2 'その他 Case Else Call cmn_ErrMsgDsp(lngErrNum, strErrMsg) cmn_DoSelectSql = -1 End Select GoTo sub_Exit End If '列数セット lngColCnt = adoRs.Fields.Count If adoRs.RecordCount > 0 Then ←ココに上記エラーメッセージが入ってきます。。。 g_lngOraRecCnt = adoRs.RecordCount lngRowCnt = adoRs.RecordCount '受渡用変数初期化 ReDim pstrData(1 To lngRowCnt, 1 To lngColCnt) Erase objField ReDim objField(0 To lngColCnt - 1) For lngCol = 0 To lngColCnt - 1 Set objField(lngCol) = adoRs.Fields(lngCol) Next lngCol '受渡用変数セット For lngRow = 0 To (lngRowCnt - 1) For lngCol = 0 To (lngColCnt - 1) pstrData(lngRow + 1, lngCol + 1) = Cmn_NullToSpace(objField(lngCol).Value) Next lngCol adoRs.MoveNext Next lngRow End If sub_Exit: If (Not adoRs Is Nothing) Then adoRs.Close Set adoRs = Nothing End If End Function 自分で開発したものではないのですが、コレといって間違いはないように思えます。。 もし何かありましたらアドバイス等お願い致します。 ・・・集計SQLは実行できないのでしょうか。。

  • Oracle
  • 回答数2
  • ありがとう数1

みんなの回答

  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.2

ここを書き換えてみてください、ということです。 >adoRs.CursorLocation = adUseClient adUseServerに変更してうまくいけば、予想通りの理由。同じエラーが出るなら、別の理由ということになります。

  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.1

ググったら1つヒットしました。 http://support.microsoft.com/kb/267455/ja OracleのバージョンもMDACのバージョンも不明なので、MDAC2.7までならそのような事象が発生する可能性があるみたいですよ。 (確かにCubeはNOT NULL列にNULLが返ってくる可能性がありますね) サーバカーソルを使えと書いてあります。

techuchu
質問者

補足

jamshid6様 お礼の方が遅くなり申し訳ありませんでした。 回答ありがとうございました!! CUBEでNULLが返ってくるのがダメだったのですね!! 納得です。 ただ、サーバカーソルを使用するとありますがピンときません。 リンク先も見てみたのですが。。 どういうことでしょうか。(すいません。。)

関連するQ&A

  • エクセルVBAでSQLを打ちたいです

    仕事上自動化ツールを作成したいのですが、どうしてもエクセルでSQLが出来ず困っています。 やりたいこと:ボタンひとつで、エクセルシートにある表の必要な部分を取り出して別のシートに貼り付ける。 SQLでは SELECT xxxxx,data,MIN(time) As times From xxxxx WHERE ●●●="●●●" GROUP BY xxxxx,data; です。 実際に今書いているVBAが途中なのですが、 Option Explicit Sub createInsertSql() Dim newbook As Workbook Dim currentCell As Range '前処理 Dim srcSheet As Worksheet Set srcSheet = ActiveSheet Dim targetRange As Range Set targetRange = srcSheet.UsedRange Dim head As String head = "SERECT " & srcSheet.Name & " (" Dim first As Boolean first = True Dim currentColumnIndex As Integer For currentColumnIndex = 1 To targetRange.Columns.Count If (first) Then first = False Else head = head & "xxxxx,data,MIN(time)" End If Set currentCell = srcSheet.Cells(1, currentColumnIndex) head = head & currentCell.Value Next head = head & ") " '新しいBook作成 Set newbook = Workbooks.Add Dim currentRowIndex As Integer For currentRowIndex = 2 To targetRange.Rows.Count Dim sql As String sql = head & "values (" first = True For currentColumnIndex = 1 To targetRange.Columns.Count If (first) Then first = False Else sql = sql & "," End If Set currentCell = srcSheet.Cells(currentRowIndex, currentColumnIndex) If IsNull(currentCell) Or Trim(currentCell.Value) = "" Then sql = sql & "null" ElseIf IsNumeric(currentCell.Value) Then sql = sql & currentCell.Value Else sql = sql & "'" & currentCell.Value & "'" End If Next sql = sql & ");" newbook.ActiveSheet.Cells(currentRowIndex - 1, 1).Value = sql Next End Sub いろんなサイトを見ていろいろ組み合わせてみたのですが、やはり出来ず。 意味を理解しようとも中々できずです。 恐れ入りますが、答えまではいかなくとも、どのようにしたらいいかのヒントだけでも いただけると嬉しいです。 よろしくお願いします。

  • VB6でのSQL実行について

    VB6でのSQL実行について VB6でのSQL実行について困っています。 SQL文を作成し、ダイナセットで実行している最中にも 再度別のSQL文をダイナセットで実行することは可能なのでしょうか? 言語はVB6.0、DBはOracle9iを使用しています。 イメージ的にはこんな使い方をしたいです。 dim lngRecordRow1 as long 'レコード数1 dim lngRecordRow2 as long 'レコード数2 dim OraDynaset1 As OraDynaset dim OraDynaset2 As OraDynaset dim strSQL as string 'SQL文 dim lngCnt1 as long 'ループカウンタ1 dim lngCnt2 as long 'ループカウンタ2 strSQL= ---SQL文作成1回目--- Set OraDynaset1 = OraDatabase.CreateDynaset(strSQL, ORADYN_READONLY) 'SQL文実行1回目 lngRecordRow1 = OraDynaset1.RecordCount for lngCnt1 = 1 to lngRecordRow1 '--- 処理 --- strSQL= ---SQL文作成2回目--- Set OraDynaset2 = OraDatabase.CreateDynaset(strSQL, ORADYN_READONLY) 'SQL文実行2回目 lngRecordRow2 = OraDynaset2.RecordCount for lngCnt2 = 1 to lngRecordRow2 '--- 処理 --- next lngCnt2 next lngCnt1 1回目で取得したSQL実行結果を行単位でループをまわしつつ、1回目で取得したレコードの結果を条件に使用して別のSQL文を作成し、ループをまわしている最中に実行したいです。 その際、2回目のSQLの結果が2レコード以上の場合、さらにループをまわして条件判別をしたいです。 かなり困っています。回答待ってます。

  • ACCESSのSQL文

    ACCESSのSQL文 いつもお世話になります。 SQL文でテーブルのデータを抽出したいのですが上手くいきません。 Dim rs4 As ADODB.Recordset Dim cmdrs4 As New ADODB.Command Set cmdrs4.ActiveConnection = CurrentProject.Connection a = "SELECT 管理NO" & " FROM マスタ" If strFlter = "" Then a = a & ";" Else a = a & " WHERE " & strFlter & ";" End If cmdrs4.CommandText = a Set rs4 = cmdrs4.Execute() MsgBox rs4.GetString aの内容は a = "SELECT 管理NO FROM マスタ WHERE 管理NO Like ""*2*"";" 実行すると、rs4.GetString文で下記エラーが出ます。 「BOFとEOFのいづれかがTrueになっているか、または現在のレコードが削除されています。 要求された操作には、現在のレコードが必要です。」 aを "SELECT 管理NO FROM マスタ WHERE 管理NO = ""2-6"";" なら問題ありません。 Likeの使い方が悪いのでしょうか? よろしくお願いします。

  • EXCEL VBA データのある範囲の特定が悪い?  

    アンケート調査票を簡単につくために、下のようなマクロを教えていただいたのですが、もとデータ項目の参照範囲がセルのB5より上にあるもの(空白の場合も)も項目としてしまっているようなので、どこを手直しすればいいのか、すみませんが教えてください。 Sub test() '定数の設定 Const strInputSheet As String = "Sheet1" Const lngInputRow As Long = 5 Const lngInputCol As Long = 2 Const strOutputSheet As String = "Sheet2" Const lngOutputCol As Long = 3 Const lngOutputRow As Long = 4 Const strMessageA As String = " は " Const strMessageB As String = " に対してどの位影響があると思いますか?" '定義 Dim lngMaxRow As Long Dim lngCountA As Long Dim lngCountB As Long Dim strA As String Dim strB As String Dim lngRow As Long '項目数を把握 Sheets(strInputSheet).Select Cells(ActiveSheet.Rows.Count, lngInputCol).Select Selection.End(xlUp).Select lngMaxRow = Selection.Row 'B列のデータ最終行を取得 lngRow = lngOutputRow '出力開始行の設定 '項目Aをなめる For lngCountA = lngInputRow To lngMaxRow  strA = Cells(lngCountA, lngInputCol).Value '項目Aの取得  '項目Bをなめる  For lngCountB = 1 To lngMaxRow   If lngCountA <> lngCountB Then '項目Aと項目Bが同じときはここは処理しない    strB = Cells(lngCountB, lngInputCol).Value '項目Bを取得    Sheets(strOutputSheet).Cells(lngRow, lngOutputCol).Value = strA & strMessageA & strB & strMessageB '文字列を結合    lngRow = lngRow + 1 '改行する   End If  Next lngCountB Next lngCountA End Sub

  • ACCESSの SELECT SUM

    SELECT SUMを 計算させると ゼロしか 出てきません。 どこが悪いのでしょうか?  日付         出金       氏名 2012/12/10      540      安田 2012/12/10      1020      斉藤 2012/12/10       970      TOM 2012/12/11      650      池田  2012/12/11     2010      南 2012/12/12      350      林田 2012/12/12     1200      加藤 のようなテーブルがあり Private Sub コマンド_click() Dim Db As Database Dim SQL As String Dim rs As Recordset Dim gokei As Long Set Db = CurrentDb SQL = "SELECT Sum(出金) as gokei FROM テーブル  WHERE 日付= #" & [Forms]![フォームアルファ]![テキスト] & "# " Set rs = Db.OpenRecordset(SQL) MsgBox gokei End Sub を フォームアルファに 新しく作ったコマンドボタンのクリック時に 書きました。 これを テキストの日付を変えておいて いろいろ試しても ゼロのメッセージしか出ません。 WHERE以下が 間違っていないか 試しに Private Sub コマンド_click() Dim Db As Database Dim SQL As String Dim rs As Recordset Dim Count As Long Set Db = CurrentDb SQL = "SELECT (出金)  FROM テーブル  WHERE 日付= #" & [Forms]![フォームアルファ]![テキスト] & "# " Set rs = Db.OpenRecordset(SQL) If rs.EOF Then Count = 0 Else rs.MoveLast Count = rs.RecordCount End If MsgBox Count End Sub を 実行すると ちゃんと 正しいレコード数が 表示されます。 「出金」のデータ型は 長整数になっています。 どこが 悪いのでしょうか? 目的は 指定した日付の 出金の合計を取り出したいのです。 . . .

  • ADOでレコードを閉じるタイミング。。Access2000/VB6/Win2K

    レコードセットを返すFuncitonプロシージャーを作ってみたのですが。。。 下のGet_Recordsの方のレコードセットをCloseすると上の方のDisp_Dataでオブ ジェクトが閉じているといって怒られます。しかし、閉じないと下の方では開きっ ぱなしになると思うのですが。。。どのように処理すればいいのでしょうか? Public P_CN As ADODB.Connection Private Sub Disp_Date()   Dim RS As ADODB.Recordset   Dim SQL AS String    Set RS = Get_Records(SQL)     With RS      If .RecordCount > 0 Then       .MoveLast: .MoveFirst       .Debug.Print !顧客_ID        End If      End With      RS.Close     Set RS = Nothing End Sub Public Function Get_Records(pSQL As String) As ADODB.Recordset   Dim RS As ADODB.Recordset     Set RS = New ADODB.Recordset      RS.Open pSQL, P_CN, adOpenKeyset, adLockOptimistic     Set Get_Records = RS '''    RS.Close '''   Set RS = Nothing End Function

  • 子画面を読んだ後親画面のRecordsetClon

    同じレコードソースを持つ帳票フォームAとポップアップ画面Bがあり 新規作成ボタンイベントで、Aからで新規入力用のB画面を acAddNew, acDialogで開き 新規レーコドを追加する作業をして B画面の保存ボタンを押すことでしてレコードを保存しています。 ◆B画面の保存ボタンの処理 Private Sub cmd保存_Click()   '保存処理   Dim i As Long   Dim NewKey As Long   Dim SQL As String   Dim lngCurrentRec As Long      If Me.Dirty = True Then     Ret = MsgBox("入力したデータを保存しますか。", vbQuestion + vbOKCancel)     If Ret = vbCancel Then       cmd取消_Click       GoTo exitH     End If     Set Me.ClsDao_ = New ClsDao     SQL = "Select final_value, [更新日時] from T95ID管理表 "     SQL = SQL & "where "     SQL = SQL & " ID_Name = '作業記録ID';"          NewKey = Me.ClsDao_.SelectID(SQL)     Me.作業記録ID.Value = NewKey          Me.BeforeUpdate = ""     DoCmd.RunCommand acCmdSaveRecord          '採番テーブルに新しいNoで更新をする     ClsDao.UpdateID NewKey     modPub.lngNewRecID = NewKey 'Global変数に新しいID NOをセット(親画面で取得するため)     Set ClsDao = Nothing          BeforeUpdate = "[イベント プロシージャ]"   '  Me.Visible = False     DoCmd.Close   End If End Sub ◆B画面の保存ボタンの処理終わり    その後、呼出元のB画面を開くイベントの処理を継続し A画面を更新し、新規入力されたレコードを選択する処理をしています。 問題は、まず1回目には、新規作成ボタンを押して新規データを登録し A画面でその新規レコードを選択することが1回目は可能で 同じ事を2回目すると、 ※実行時エラー'7951':  RecordSetCloneプロパティに対する不適切な参照を含む式を入力しました。 というエラーが出ます。 その時の画面は、複数行あったのが一レコードだけになってしまい、 各項目のTextboxは、「#Name?」が表示されています。 デバッグボタンを押すと 以下のソースの「Set Rec = Me.RecordsetClone」で止まります。 この解決方法を教えて下さい。 ◆A画面の新規作成ボタンのソースの内容開始 Private Sub cmdNewRec_Click()   Dim ClsDao As ClsDao   Dim SQL As String   Dim NewFm As Form   Dim Rec As Recordset   Dim NewNo As Long   Dim MyFm As Form   Dim StrRecSource As String      Set MyFm = Me.Form    StrRecSource = Me.RecordSource      DoCmd.OpenForm "FXX作業記録(NewEntry_連結版)", acNormal, , , acFormAdd, acDialog      If modPub.lngNewRecID > 0 Then     NewNo = modPub.lngNewRecID     Me.RecordSource = StrRecSource     Me.Requery     Set Rec = Me.RecordsetClone <===ここでエラー     Rec.FindFirst "作業記録ID = " & NewNo     If Rec.NoMatch = False Then '      Me.CurrentRecord = Rec.AbsolutePosition       DoCmd.GoToRecord acDataForm, Me.Name, acGoTo, Rec.AbsolutePosition + 1       Rec.Close       Set Rec = Nothing     End If   End If End Sub ◆A画面の新規作成ボタンのソースの内容終了

  • SQLの条件に変数を

    はじめまして。よろしくお願いします select文のwhere条件にidを指定したいのですがうまくいきません。 べつに変数を使用しなくてもよいのですが良い方法がありましたらご教授下さい Private Sub コマンド8_Click() Dim adoCON As ADODB.Connection Dim adoRS As ADODB.Recordset Dim no As interger no=me.id Set adoCON = Application.CurrentProject.Connection Set adoRS=adoCON.Execute("select varcodeno from varcode_tbl where id=no")strName = adoRS!varcodeno adoRS.Close adoCON.Close Set adoRS = Nothing Set adoCON = Nothing Me.jancode.Value = strName End Sub

  • Accessから値を抽出しようとするとフリーズする

    Excelからマクロを用いてAccessファイルからデータを拾おうとしています。 方法は、Access内のテーブルを参照して検索対象の値1がフィールド内にあれば、その行の値2を抽出してくるといったものです。 検索対象の数は可変です。 そこでコードを書いてみたところ 抽出件数が2件以上なら正常に動作するのですが 1件、0件だと動作せず、フリーズしてしまいます。 何が原因で、どう書き直せばよいのでしょうか? 以下、コードです。 Private Sub OKButton_Click() '選択し、OKボタンを押した時 Dim p As Long Dim cnt As Long Range(Cells(45, 4), Cells(114, 6)).ClearContents 'D45~E115のセルを削除(二回目使用時にデータが残ってる為) cnt = ListView1.ListItems.Count '今まで選択してリストビューに追加された対象数を出し、変数へ。 For p = 1 To cnt Cells(44 + p, 4).Value = ListView1.ListItems.Item(p) Cells(44 + p, 5).Value = ListView1.ListItems.Item(p).SubItems(1) Cells(44 + p, 6).Value = ListView1.ListItems.Item(p).SubItems(2) Next p 'リストビューに追加された対象を、D45~E115に書き込み Dim Sql As String Dim i As Long Dim j As Long Dim k As Long Dim m As Long Dim n As Long Call DBconnect(True) Sql = _ "select Aコード,Bコード " & _ "from テーブル" '--- adoRsにSELECT文を入れ、絞り込む adoRs.Open Sql, adoCn, adOpenKeyset ' --- j:選択した対象の数を取得 k:Access内の選択した対象のデータ数を取得 n:列数 j = Worksheets("選択").Range("F45").End(xlDown).Row k = adoRs.Fields.Count n = 1 '--- Aコードが一致する行を選択シートの下部分へ書き込み。 ' --- 45 to jの45は、選択シートの選択した対象をセルに出力した場所が45行目の為。 ' --- cell(j+n,6)は、選択対象数を起点にBコード(値2)一つ毎に数を足していく、6はF列 Do Until adoRs.EOF For i = 45 To j If Worksheets("選択").Cells(i, 6).Value = adoRs!Aコード Then For m = 1 To k Worksheets("選択").Cells(j + n, 6) = adoRs.Fields!Bコード Next m n = n + 1 End If Next i adoRs.MoveNext Loop '後始末 adoRs.Close: Set adoRs = Nothing adoCn.Close: Set adoCn = Nothing

  • カレントレコードが無い事を判定させる方法

    SQLを使ってmdb内のレコードセットを取得し、 無かったらエラーを返す、という処理を作成 する場合、カレントレコードが無い事を 判定するにはどうすれば良いでしょうか? イメージは下記のような感じです。 レコードセット as DAO.Recordset 'レコードセット取得  Set レコードセット = db.OpenRecordset(作成したSQL文) '判定 If カレントレコード無 Then MsgBox "エラーメッセージ" Exit Sub End If