Ruby on Rails и MSSQL Server: попытка вставить строки со значениями по умолчанию newid()

(этот вопрос изначально был размещен на другом форуме несколько месяцев назад, но не получил ответа ... в то время не было ТАК!)

Мои первые шаги в RoR. Я купил одну из этих книг, рассказывающих о Ruby и Ruby On Rails. Примеры правильно работают на MySQL, поэтому я решил переписать их для MS-SQL в качестве хорошего упражнения (а поскольку MS-SQL является нашей стандартной базой данных).. и это превратилось в дурной сон:

У меня есть эта таблица с 2 полями

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

У меня есть подключение ODBC к базе данных. Я могу перечислить записи, но... никакие вставки в таблицу сделать не могу. Строка INSERT, сгенерированная Ruby, выглядит следующим образом:

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

И будет отклонено, потому что строка 'newid' не может быть вставлена ​​в поле уникального идентификатора/первичного ключа id_People. Логически возвращается ошибка:

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

Это кажется настолько очевидной большой и основной проблемой, что я чувствую, что пропустил что-то, что обычно написано жирным шрифтом в каждом учебном документе RoR, например, «Не пытайтесь использовать INSERT через RoR», «uniqueIdentifier является китайским для RoR» или «RoR не не работает с MS SQL Server'...

Есть идеи?


person Philippe Grondier    schedule 23.01.2009    source источник


Ответы (2)


Я не сторонник Ruby, так что имейте это в виду. Большая часть этого просто потеряна в переводе MySQL-> MSSQL IMO.

Итак, ваш идентификатор имеет тип «uniqueidentifier». Должно произойти одно из двух:

а) вы должны передать NEWID() в качестве первого параметра. Не строка 'newid', а функция NEWID()

б) не передавать в первом параметре. Поскольку есть значение по умолчанию, просто вставьте его в столбец NamePeople.

В зависимости от использования я бы использовал только первичные ключи uniqueidentifier, если вы имеете дело с распределенными данными, и придерживался бы старых добрых столбцов INT IDENTITY для большинства ключевых ссылок.

person Joe    schedule 23.01.2009
comment
строка INSERT автоматически генерируется RUBY, а не мной. Способ, которым RUBY генерирует строку, явно неверен. - person Philippe Grondier; 23.01.2009

Посмотрите этот пост, другой тип БД, но по сути та же проблема, как скрыть поля по умолчанию от RoR, чтобы не генерировалась недопустимая вставка.

EDIT @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
person cmsjr    schedule 23.01.2009
comment
Спасибо. Проблема, раскрытая в этом блоге, совершенно иная, но все же представляет общий интерес. Прочитав это, я мог бы создать функцию для генерации значений uniqueId на стороне клиента. - person Philippe Grondier; 23.01.2009
comment
К сожалению, ссылка уже мертва. - person Wayne Conrad; 19.12.2015