- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我的 Ruby on Rails 系统正在从 Oracle 迁移到 Microsoft SQL Server 2012。后端数据库已经由第三方从 Oracle 转换为 Microsoft SQL Server。我无法控制架构结构。这是无法更改的。
使用 activerecord-sqlserver-adapter、tiny_tds 和 Freetds 我可以连接到新数据库。大多数数据库请求运行良好。
但是,许多表具有由 SQL Server 自动递增的 ID 主键,换句话说,PK IDENTITY(1,1) 列。使用 Oracle 连接的相同代码在 SQL Server 下失败并出现以下错误:
TinyTds::Error: Cannot insert the value NULL into column 'ID'
我知道它为什么这样做,因为 ID 列确实是一个主键和 IDENTITY(1,1) 列,并且包含 NOT NULL 限制。没事儿。
如果使用原始 SQL 执行语句,插入到表中工作正常,当然我从 INSERT 语句中排除了 ID 列。
但是我花了几天时间在谷歌上搜索,但我找不到告诉 Ruby on Rails 不要尝试保存 ID 列的方法。
所以我有一个类的实例,@book,它包含
Library::Book(id: integer, title: string, isbn: string ...)
当我执行 @book.save 时!它会产生上述错误。
@book = Library::Book.new( .. )
:
:
@book.save!
TinyTds::Error: Cannot insert the value NULL into column 'ID'
而不是求助于裸机 SQL,我如何做更多 Railsy 的事情并告诉它我想保存记录但不尝试保存 ID 字段,因为它是自动递增的?如此有效,我正在尝试保存
Library::Book(title: string, isbn: string ...) 如果一个新的插入条目或者Library::Book(id: integer, title: string, isbn: string ...) 如果尝试更新条目。
由于强加的限制,我正在使用: ruby 2.3.3p222 rails 4.0.13事件记录 (4.0.13)activerecord-sqlserver-adapter (4.0.4)tiny_tds (1.0.2)Freetds 1.00.27
最佳答案
您可以使用 ActiveRecord::Relation#find_or_initialize_by .这假设您当时有足够的已知属性来唯一标识记录。
这将解决您问题的最后一部分。但听起来 id
列未设置为自动递增。您需要设置它,以便当 Rails 发送一个 null
id 时,数据库将正确设置它。
更新:要使列自动递增,您需要运行迁移。然后你可以这样做:
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
这很糟糕,如果可能的话,我强烈建议更新专栏。
关于ruby-on-rails - TinyTds::错误:无法将值 NULL 插入列 'ID',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54592586/
我是一名优秀的程序员,十分优秀!