这是场景。
我正在为 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] (这是我的数据库中 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)
- 导轨版本 3.2.5
- 活动记录版本 3.2.5