2

これがシナリオです。
Ruby On Rails 用の geo-ruby oracle アダプターを作成しています。これは、すぐに使用できる SDO_GEOMETRY の操作をサポートします。
順調でした。Oracle DB から SDO_GEOMETRY オブジェクトを正常に選択するためのコードを作成しました。
挿入部分と更新部分を書きたいと思ったとき、すべてが台無しになりました。
以下は私の心に残っていることです。私はこのステートメントを実行できるようにしたい:

g = GeoShape.new(name:"point1", shape: Point.from_x_y(-34,-43,4326))
g.save

上記のステートメントから次の SQL クエリを生成しました。

INSERT INTO "GEO_SHAPES" ("CREATED_AT", "ID", "NAME", "SHAPE", "UPDATED_AT") VALUES (:a1, :a2, :a3, :a4, :a5)  [["created_at", Tue, 03 Jul 2012 08:42:01 UTC +00:00], ["id", 10112], ["name", "point1"], ["shape", "SDO_GEOMETRY(2001,  NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(-34,-43))"], ["updated_at", Tue, 03 Jul 2012 08:42:01 UTC +00:00]]

しかし、上記のクエリを実行すると、次のエラーが発生しました。

ActiveRecord::StatementInvalid: OCIError: ORA-00932: inconsistent datatypes: expected MDSYS.SDO_GEOMETRY got CHAR

問題を追跡するために oracle_enhanced_adapter に入りました。次のように、モンキー パッチを適用し、binds[3][1] (DB の sdo_geometry 列の値) を手動で初期化しようとしました。

    def exec_insert(sql, name, binds)
    log(sql, name, binds) do
      returning_id_index = nil
      cursor = if @statements.key?(sql)
        @statements[sql]
      else
        @statements[sql] = @connection.prepare(sql)
      end

    binds[3][1] = "SDO_GEOMETRY(2001,  NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(-34,-43))" ### DAVE

      binds.each_with_index do |bind, i|
        col, val = bind
        if col == :returning_id
          returning_id_index = i + 1
          cursor.bind_returning_param(returning_id_index, Integer)
        else
          if val == "SDO_GEOMETRY(2001,  NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1,1), SDO_ORDINATE_ARRAY(-34,-43))" ### DAVE
            cursor.bind_param(i + 1, val, OCI8::Object::Mdsys::SdoGeometry) ###DAVE
          else ### DAVE
            cursor.bind_param(i + 1, type_cast(val, col), col && col.type)
          end
        end
      end

      cursor.exec_update

残念ながら、それは役に立ちませんでした。それでも同じエラー ORA-00932 が発生します。何か案は?これを修正することは私にとって非常に重要です。

PS: ###DAVE の部分は、oracle_enhanced_adapter.rb のモンキー パッチです。
PS: これが私の設定です。

  • オラクル 11.2
  • Ruby バージョン 1.9.3 (i386-darwin11.3.0)
  • Rails バージョン 3.2.5
  • アクティブレコード バージョン 3.2.5
4

1 に答える 1

0

最後に、問題を解決することができました。
拡張アダプターは bind_param メソッドを使用して、変数を適切な Oracle タイプにバインドします。ここに問題とエラーがありました。
oracle_enhanced_adpter.rb のいくつかのコードをオーバーライドする必要がありました。
このファイルにメソッドを追加して、SDO_GEOMETRY オブジェクトを手動で作成します。
次に、この返されたオブジェクトを OCI8::Object::Mdsys::SdoGeometry 型にバインドします。

私のメソッドには次のコードが含まれています (現在は、SDO_GEOMETRY ポイントの作成のみ):

#I needed a connection to my oracle database. Connection placeholder is conn.
def create_sdo_geometry_object(conn, gtype, srid, point, x, y)
    local_cursor = conn.parse("BEGIN :geom := SDO_GEOMETRY(:sdo_gtype, :sdo_srid, :sdo_point, :sdo_elem_info_array, :sdo_ordinate_array); END;")
    local_cursor.bind_param(:sdo_gtype, OraNumber)
    local_cursor.bind_param(:sdo_srid, OraNumber) 
    local_cursor.bind_param(:sdo_point, OCI8::Object::Mdsys::SdoPointType) 
    local_cursor.bind_param(:sdo_elem_info_array, OCI8::Object::Mdsys::SdoElemInfoArray)
    local_cursor.bind_param(:sdo_ordinate_array, OCI8::Object::Mdsys::SdoOrdinateArray)

    local_cursor.bind_param(:geom, OCI8::Object::Mdsys::SdoGeometry)

    sdo_gtype = OraNumber.new(gtype)
    sdo_srid = OraNumber.new(srid)
    sdo_point = nil #Temporarily I set it to nil


    #sdo_elem_info_array must be [1,1,1] for creating points.
    sdo_elem_info_array = OCI8::Object::Mdsys::SdoElemInfoArray.new(conn,OraNumber.new(1),OraNumber.new(1),OraNumber.new(1))
    #I want to create a point with x and y coordinates
    sdo_ordinate_array = OCI8::Object::Mdsys::SdoOrdinateArray.new(conn,OraNumber.new(x),OraNumber.new(y))

    local_cursor[:sdo_gtype] = sdo_gtype
    local_cursor[:sdo_srid] = sdo_srid
    local_cursor[:sdo_point] = sdo_point
    local_cursor[:sdo_elem_info_array] = sdo_elem_info_array
    local_cursor[:sdo_ordinate_array] = sdo_ordinate_array
    local_cursor.exec

    local_cursor[:geom]
end

次に、このパラメーターをバインドしたいときに、次のコードを使用しました。

cursor.bind_param(i + 1, create_sdo_geometry_object("PARAMS HERE"), OCI8::Object::Mdsys::SdoGeometry)

それは魅力のように働きました!

于 2012-07-04T06:45:28.273 に答える