Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails TinyTds::错误:无法将值NULL插入列';ID';_Ruby On Rails_Ruby_Activerecord_Sql Server 2012_Tiny Tds - Fatal编程技术网

Ruby on rails TinyTds::错误:无法将值NULL插入列';ID';

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

我的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时!它生成上述错误

@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
看起来更简洁一些