由ActiveRecord创建时,Oracle序列不可见

时间:2017-02-03 19:22:42

标签: ruby oracle activerecord

我使用ActiveRecord迁移在Oracle数据库中创建表和序列,但我无法使用它创建的序列。

这是我尝试的简单迁移:

class CreateFoo < ActiveRecord::Migration
   def self.up
     create_table "FOO" do |t|
       t.string   "name",     :limit => 50
       t.integer  "age"
     end
   end

   def self.down
     drop_table "FOO"
   end
end

但是,当我尝试在该表中插入记录时,它无法找到序列。

SQL> insert into foo values(foo_seq.nextval, 'bob', 10);
insert into foo values(foo_seq.nextval, 'bob', 10)
                       *
ERROR at line 1:
ORA-02289: sequence does not exist

序列确实存在,但名称是大小写混合。 Oracle是否区分大小写?

SQL> select sequence_name from user_sequences;

SEQUENCE_NAME
------------------------------
FOO_seq

更改序列名称的大小写以匹配并不帮助。

SQL> insert into foo values(FOO_seq.nextval, 'bob', 10);
insert into foo values(FOO_seq.nextval, 'bob', 10)
                       *
ERROR at line 1:
ORA-02289: sequence does not exist

如何让ActiveRecord返回创建正常序列?这曾经适合我,但可能是旧版本的ActiveRecord。我现在正在使用activerecord 4.0.13和activerecord-oracle_enhanced-adapter 1.5.6。

1 个答案:

答案 0 :(得分:2)

问题

在做了一些研究后,我发现如果在创建对象时使用quotes,Oracle对象可能会出现区分大小写的名称。

  
      
  1. 不带引号的标识符不区分大小写。 Oracle将它们解释为大写。带引号的标识符区分大小写。
  2.   

如果引用它的名字,我可以使用该序列。

SQL> insert into foo values("FOO_seq".nextval, 'bob', 10);

1 row created.

很好,我理解Oracle正在做什么,但为什么ActiveRecord在创建序列时会使用引号?在深入研究activerecord-oracle_enhanced-adapter源代码之后,我找到了原因。要创建序列名称,它会附加&#34; _seq&#34;到表名。因为结果是混合大小写,所以它会添加引号。

解决方案

只需在迁移中将表名切换为小写,然后整个序列名称将为小写,并且它不会被引用。这将使它不区分大小写。

class CreateFoo < ActiveRecord::Migration
   def self.up
     create_table "foo" do |t|
       t.string   "name",     :limit => 50
       t.integer  "age"
     end
   end

   def self.down
     drop_table "foo"
   end
end