2

(这个问题最初是几个月前在另一个论坛上发布的,没有得到任何答案......这些时候没有SO!)

我在 RoR 的第一步。我买了一本关于 Ruby 和 Ruby On Rails 的书。示例在 MySQL 上运行正确,所以我决定为 MS-SQL 重写它们作为一个很好的练习(因为 MS-SQL 是我们的标准数据库)......它变成了一个噩梦:

我有这个有 2 个字段的表

Tbl_People
----------
id_People        primary key, newid() default value,
namePeople       string

我有一个到数据库的 ODBC 连接。我可以列出记录,但是……我不能在表中插入任何内容。Ruby 生成的 INSERT 字符串如下:

INSERT INTO Tbl_People (id_People, namePeople) VALUES('newid','GRONDIER, Philippe')

并且将被拒绝,因为字符串 'newid' 不能插入到 uniqueindentifier/primary key field 中id_People。从逻辑上讲,返回的错误是:

DBI::DatabaseError: 37000 (8169) [Microsoft] [ODBC SQL Server Driver][SQL Server]Conversion failed when converting from a character string to uniqueidentifier

这似乎是一个大而基本的问题,我觉得我错过了通常在每个 RoR 培训文档上用粗体写的东西,例如“不要尝试通过 RoR 插入”、“uniqueIdentifier is Chinese to RoR”或“RoR does '不适用于 MS SQL Server'...

任何想法?

4

2 回答 2

1

我不是 Ruby 人,所以请记住这一点。其中大部分只是在 MySQL->MSSQL 翻译 IMO 中丢失了。

因此,您的 id 属于“uniqueidentifier”类型。应该发生以下两件事之一:

a) 你应该传入 NEWID() 作为第一个参数。不是字符串“newid”,而是函数 NEWID()

b) 不要传入第一个参数。由于有默认值,只需插入 NamePeople 列。

根据使用情况,如果您正在处理分布式数据,我只会使用 uniqueidentifier 主键,并且对于大多数键引用坚持使用良好的旧 INT IDENTITY 列。

于 2009-01-23T01:51:42.997 回答
1

查看这篇文章,不同的数据库类型,但本质上是相同的问题,如何从 RoR 隐藏默认字段,因此不会生成无效插入。

编辑@wayne-conrad 指出旧链接已失效。我相信内容是在这里找到的, http: //inodes.org/2008/01/11/rails-activerecord-mysql-guids-and-the-rename_column-bug/

关键摘录如下。

该页面的评论部分还引用了一个旨在解决问题的项目 https://github.com/cch1/uuid_primary_key/tree/master(链接现在不会让我失望!)

 # HACK (JF) - This is too evil to even blog about
  # When we use guid as a primary key we usually rename the original 'id'
  # field to 'integer_id'. We need to hide this from rails so it doesn't
  # mess with it. WARNING: This means once you use usesguid anywhere you can
  # never access a column in any table anywhere called 'integer_id'

class ActiveRecord::Base
  private
    alias :original_attributes_with_quotes :attributes_with_quotes

    def attributes_with_quotes(include_primary_key = true, include_readonly_attributes = true)
      quoted = original_attributes_with_quotes(include_primary_key = true, include_readonly_attributes = true)
      quoted.delete('integer_id')
      quoted
    end
end
于 2009-01-23T01:59:27.050 回答