これがシナリオです。
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