gpt4 book ai didi

ruby-on-rails - 获取 OCIError : ORA-00932: inconsistent datatypes From Rails 3

转载 作者:太空宇宙 更新时间:2023-11-03 16:55:27 24 4
gpt4 key购买 nike

这是场景。
我正在为 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 来跟踪问题。我尝试对其进行猴子修补并手动初始化绑定(bind) [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。有任何想法吗?解决这个问题对我来说非常重要。

P.S:###DAVE 部分是我的 oracle_enhanced_adapter.rb 猴子补丁
P.S: 这是我的配置。

  • 甲骨文 11.2
  • Ruby 版本 1.9.3 (i386-darwin11.3.0)
  • Rails 版本 3.2.5
  • 事件记录版本 3.2.5

最佳答案

最后,我设法解决了这个问题。
增强型适配器使用 bind_param 方法将变量绑定(bind)到它们适当的 oracle 类型。这是问题和错误。
我不得不覆盖 oracle_enhanced_adpter.rb 中的一些代码。
我在这个文件中添加了一个方法来手动构建 SDO_GEOMETRY 对象。
然后我将这个返回的对象绑定(bind)到 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

然后当我想绑定(bind)这个参数时,我使用了下面的代码:

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

它就像一个魅力!

关于ruby-on-rails - 获取 OCIError : ORA-00932: inconsistent datatypes From Rails 3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11307732/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com