Ruby on rails TinyTds::错误:无法将值NULL插入列';ID';
我的Ruby on Rails系统正在从Oracle迁移到Microsoft SQL Server 2012。后端数据库已由第三方从Oracle转换为Microsoft SQL Server。我无法控制模式结构。这是无法改变的 使用activerecord sqlserver适配器、tiny_tds和Freetds,我可以连接到新数据库。大多数数据库请求工作正常 但是,许多表都具有由SQL Server自动递增的ID主键,即PK IDENTITY(1,1)列。使用Oracle连接的同一代码在SQL Server下失败,错误如下: TinyTds::错误:无法将值NULL插入列“ID” 我知道它为什么这样做,因为ID列实际上是一个主键,而IDENTITY(1,1)列包含notnull限制。那很好 如果使用原始的SQL execute语句(当然我从INSERT语句中排除了ID列),则插入到表中的操作很好 然而,我花了好几天时间在谷歌上搜索,我找不到一种方法告诉RubyonRails不要尝试保存ID列 所以我有一个类@book的实例,它包含 图书库::图书(id:整数,标题:字符串,isbn:字符串…) 当我做@book.save时!它生成上述错误Ruby on rails TinyTds::错误:无法将值NULL插入列';ID';,ruby-on-rails,ruby,activerecord,sql-server-2012,tiny-tds,Ruby On Rails,Ruby,Activerecord,Sql Server 2012,Tiny Tds,我的Ruby on Rails系统正在从Oracle迁移到Microsoft SQL Server 2012。后端数据库已由第三方从Oracle转换为Microsoft SQL Server。我无法控制模式结构。这是无法改变的 使用activerecord sqlserver适配器、tiny_tds和Freetds,我可以连接到新数据库。大多数数据库请求工作正常 但是,许多表都具有由SQL Server自动递增的ID主键,即PK IDENTITY(1,1)列。使用Oracle连接的同一代码在SQ
@book = Library::Book.new( .. )
:
:
@book.save!
TinyTds::错误:无法将值NULL插入列“ID”
与其求助于裸机SQL,不如说我如何做得更轻率一些,告诉它我想保存记录,但不尝试保存ID字段,因为它是自动递增的?所以我实际上是在努力拯救
Library::Book(标题:string,isbn:string…)如果插入新条目
或
Library::Book(id:integer,title:string,isbn:string…)如果尝试更新条目
由于受到限制,我正在使用:
Ruby 2.3.3p222
Rails 4.0.13
activerecord(4.0.13)
activerecord sqlserver适配器(4.0.4)
tiny_tds(1.0.2)
Freetds 1.00.27您可以使用。这假设您当时有足够的已知属性来唯一标识记录
这将解决你问题的最后一部分。但是听起来好像id
列没有设置为自动递增。您需要设置它,这样当Rails发送null
id时,DB将正确地设置它
更新:要使列自动递增,需要运行迁移。然后,您可以执行以下操作:
Alter table books modify column id int(11) auto_increment;
更新:如果无法修改数据库,则可以执行以下操作:
class Book
private
def create_or_update(*args, &block)
self.id ||= Book.maximum(:id) + 1
super
rescue ActiveRecord::RecordNotUnique
self.id = nil
retry
end
end
非常简陋,如果可能的话,我强烈建议更新该专栏。谢谢汤姆。这就是我一直试图找到的,一种告诉Rails ID列是自动递增类型的方法。我找不到执行此操作的语句或语法。我在模型中有self.primary\u key=“id”。是否需要修改此属性或在其他位置定义“自动增量”属性?我看到的一些建议在我的环境中似乎不受支持。@user321321我用迁移更新了我的答案,以更改列的行为。Microsoft SQL Server表是固定的,其ID定义如下。我不能改变它。[ID][numeric](18,0)标识(1,1)不为空。上面的迁移会修改DB的结构吗?@user321321我添加了一种方法,如果不允许修改DB,可以覆盖Rails行为。为什么不
self.id | |=Book.max(:id)。to_I+1
看起来更简洁一些