6 Replies Latest reply: Sep 5, 2012 1:36 AM by 959264 RSS

    oo4o の FieldIndex を ODP.net に置き換える方法を教えて下さい。

    959264
      OS:Windows 7
      開発ツール VoisualStadio 2010 (VB.Net)
      ODP.NET 10.1.0.200

      現在 oo4o → ODP.net の移行作業をしております。
      対応する機能がどうしても見つけ切らなかったので質問させて頂きました。


      【oo4o】
       iCol = odyna.FieldIndex("SUM(NVL(フィールド名,0))")

      oo4oでは上記にてフィールド番号を取得しております。
      ODP.net で実現するにはどのようにすれば良いのでしょうか?

      ※ ODP.net では DataSetを使用し置き換えを行っております。
      但し、DataSet に拘りは無いので ExecuteReader を使用する方法でも構いません


      ご存知の方がいらっしゃいましたら、御教授ください。
      よろしくお願いします。
        • 1. Re: oo4o の FieldIndex を ODP.net に置き換える方法を教えて下さい。
          hamadeguchi
          DataSetではどうだったか失念しましたが
          DataReaderであればGetOrdinalで取得できたはずです。
          • 2. Re: oo4o の FieldIndex を ODP.net に置き換える方法を教えて下さい。
            959264
            回答ありがとうございます。早速試してみました。

            結果としては
             iCol = r.GetOrdinal("SUM(NVL(フィールド名, 0))")
            上記は "結果セットに指定した列が見つかりません。" とエラーが発生しました。

            ※ oo4o ではSQL文内で使用している文字列なら式だろうと別名だろうと取得できるようなのですが、
            ODP.net の GetOrdinal ではエラーになるようです?

            ちなみに、 iCol = r.GetOrdinal("フィールド名") ではエラーにならず、意図した値が取得できました。

            他に互換性のある機能はありませんでしょうか?
            もしくは、変換方法が間違っているなどありましたら引き続き御教授頂きたく。

            よろしくお願いします。
            • 3. Re: oo4o の FieldIndex を ODP.net に置き換える方法を教えて下さい。
              nashiOracle
              こちらでは問題なく取得できます。
              SQLが小文字でも、フィールド名が2バイト文字でも問題ないようです。
              Dim connStr As String = "User Id=xx; Password=xxx; Data Source=xxxx;"
              Using conn As Oracle.DataAccess.Client.OracleConnection = New OracleConnection
                  conn.ConnectionString = connStr
                  conn.Open()
                  Using cmd As Oracle.DataAccess.Client.OracleCommand = New OracleCommand()
                      cmd.Connection = conn
                      cmd.CommandText = "with a as (select 1 as f1, null as 日本語項目 from dual) " & _
                                                      " select f1,日本語項目,sum(nvl(f1,0)),sum(nvl(日本語項目,0)) from a"
                      Using r As Oracle.DataAccess.Client.OracleDataReader = cmd.ExecuteReader
                          Dim s As New System.Text.StringBuilder
                          If r.Read() Then
                              s.AppendLine(String.Format("{0} → {1}", "F1", r.GetOrdinal("F1")))
                              s.AppendLine(String.Format("{0} → {1}", "日本語項目", r.GetOrdinal("日本語項目")))
                              s.AppendLine(String.Format("{0} → {1}", "SUM(NVL(F1,0))", r.GetOrdinal("SUM(NVL(F1,0))")))
                              s.AppendLine(String.Format("{0} → {1}", "SUM(NVL(日本語項目,0))", r.GetOrdinal("SUM(NVL(日本語項目,0))")))
                              s.AppendLine(String.Format("{0} → {1}", "f1", r.GetOrdinal("f1")))
                              s.AppendLine(String.Format("{0} → {1}", "f2", r.GetOrdinal("日本語項目")))
                              s.AppendLine(String.Format("{0} → {1}", "sum(nvl(f1,0))", r.GetOrdinal("sum(nvl(f1,0))")))
                              s.AppendLine(String.Format("{0} → {1}", "sum(nvl(日本語項目,0))", r.GetOrdinal("sum(nvl(日本語項目,0))")))
                          End If
                          Debug.Print(s.ToString())
                      End Using
                  End Using
              End Using
              
              (実行結果)
              F1 → 0
              日本語項目 → 1
              SUM(NVL(F1,0)) → 2
              SUM(NVL(日本語項目,0)) → 3
              f1 → 0
              f2 → 1
              sum(nvl(f1,0)) → 2
              sum(nvl(日本語項目,0)) → 3
              Oracle: 11.1.0.7.0 (32bit)
              開発ツール VisualStadio 2008 (VB.Net)
              環境:OS:Windows 7
              Oracle Instant Client 11.1.0.6.0 (ODP.NETアセンブリバージョン:2.111.6.20)

              参考になれば幸いです。
              • 4. Re: oo4o の FieldIndex を ODP.net に置き換える方法を教えて下さい。
                959264
                ソースまで付けて頂き、ありがとうございます。
                凄く感謝しています。

                お陰で動いてないであろう箇所が判明しました。
                以下のように

                cmd.CommandText = "with a as (select 1 as f1, null as 日本語項目 from dual) " & _
                " select f1,日本語項目,sum(nvl(f1,0)) as goukei,sum(nvl(日本語項目,0)) from a"

                別名を付けると sum(nvl(f1,0)) が取得できなくなりました。
                → r.GetOrdinal("goukei") は取得できました。



                業務ロジックを簡略化したSQLは以下になり、取得したい値は SUM(NVL(f1, 0)) となります。
                --------------------
                with a as (select 1 as f1, 2 as f2 from dual)
                select
                sum(nvl(合計, 0)) as 大合計
                from
                (
                select
                SUM(NVL(f1, 0)) + SUM(NVL(f2, 0)) as 合計
                from
                a
                ) F1
                --------------------
                → oo4o では SUM(NVL(f1, 0)) を FieldIndexで取得できています。


                何度も大変申し訳ございません。ODP.net で上記値を取得する方法はありますでしょうか?
                また、自分が何が勘違いしているようでしたら併せて御指摘ください。

                よろしくお願いします。
                • 5. Re: oo4o の FieldIndex を ODP.net に置き換える方法を教えて下さい。
                  nashiOracle
                  >
                  → oo4o では SUM(NVL(f1, 0)) を FieldIndexで取得できています。
                  >
                  いえ、oo4oでもご提示のSQLでは取得できません。
                      On Error GoTo err_
                      Dim ssn As Object, dbs As Object, rs As Object
                      Set ssn = CreateObject("OracleInProcServer.XOraSession")
                      Set dbs = ssn.OpenDatabase("server/sid", "userid/password", 0&)
                      Dim sql As String
                      sql = "with a as (select 1 as f1, 2 as f2 from dual)" & _
                            " select " & _
                            " sum(NVL(合計, 0)) As 大合計 " & _
                            " from " & _
                            " ( " & _
                            "  select " & _
                            " SUM(NVL(f1, 0)) + SUM(NVL(f2, 0)) as 合計 " & _
                            "  from a ) F1"
                      Set rs = dbs.CreateDynaset(sql, &H4)
                      Debug.Print "大合計:" & rs.FieldIndex("大合計")
                      Debug.Print "SUM(NVL(f1, 0)):" & rs.FieldIndex("SUM(NVL(f1, 0))")
                  ext_:
                      Set rs = Nothing
                      Set dbs = Nothing
                      Set ssn = Nothing
                      Exit Sub
                  err_:
                      Debug.Print "Err:" & Err.Description
                      Resume ext_
                  
                  (実行結果)
                  大合計:0
                  Err:OIP-04099: Field 'SUM(NVL(f1, 0))' not found
                  このSQLでは結果セットに「SUM(NVL(f1, 0))」という項目が含まれていないからです。
                  個別項目の集計結果と、それらの合計(に別名をつけて)の両方を参照したいのであれば、全てをselectする必要があります。
                  Dim connStr As String = "User Id=xxx; Password=xxxx; Data Source=xxxx/xxx;"
                  Using conn As Oracle.DataAccess.Client.OracleConnection = New OracleConnection
                      conn.ConnectionString = connStr
                      conn.Open()
                      Using cmd As Oracle.DataAccess.Client.OracleCommand = New OracleCommand()
                          cmd.Connection = conn
                          cmd.CommandText = "with a as (select 1 as f1, 2 as f2 from dual) " & _
                           "select SUM(NVL(f1, 0)), SUM(NVL(f2, 0)),(SUM(NVL(f1, 0)) + SUM(NVL(f2, 0))) as 合計 from a"
                          Using r As Oracle.DataAccess.Client.OracleDataReader = cmd.ExecuteReader
                              Dim s As New System.Text.StringBuilder
                              If r.Read() Then
                                  s.AppendLine(String.Format("{0} → {1}", "SUM(NVL(f1, 0))", r.GetOrdinal("SUM(NVL(f1,0))")))
                                  s.AppendLine(String.Format("{0} → {1}", "SUM(NVL(f2, 0))", r.GetOrdinal("SUM(NVL(f2,0))")))
                                  s.AppendLine(String.Format("{0} → {1}", "合計", r.GetOrdinal("合計")))
                              End If
                              Debug.Print(s.ToString())
                          End Using
                      End Using
                  End Using
                  
                  (実行結果)
                  SUM(NVL(f1, 0)) → 0
                  SUM(NVL(f2, 0)) → 1
                  合計 → 2
                  • 6. Re: oo4o の FieldIndex を ODP.net に置き換える方法を教えて下さい。
                    959264
                    丁重な回答、感謝しております。
                    oo4oでは取得できているものと思い込んでいました。

                    結果セットに含める方向で移行を検討したいと思います。

                    hamadeguchiさん、nashiOracleさん、とても助かりました。
                    本当に有難うございました。

                    失礼します。