Rails2.3+ 使用SQL2005

  一个小型项目,历史数据库是SQL2005,不能更改数据库,所以折腾了一下午,到处查资料,终于成功的让Ruby1.8.7+Rails2.3.4在SQL2005上跑起来了。

  安装sqlserver的驱动:gem install activerecord-sqlserver-adapter

 

  安装dbi (0.4.1)后,直接使用ADO来访问SQL Server,提示无法打开ADO驱动,原来是缺少了ADO.rb这个文件,下载DBI的老版本(0.2.*),将lib/dbd_ado/ADO.rb文件拷贝到X:/ruby/lib/ruby/site_ruby/1.8/DBD/ADO/ADO.rb,再次连接数据库仍然提示无法连接,修改database.yml:

development:
  adapter: sqlserver
  database: database
  username: user
  password: pwd
  host: .\SQLEXPRESS
  mode: DBI:ADO
  provider: SQLNCLI

  注意host那里,不能填localhost,也不能填127.0.0.1,否则无法连接到数据库,不知道为什么。

 

  现在可以正常连接到数据库了,但是查询出来的结果仍然为乱码,在database.yml中设置encoding无效,解决方法为:在environment.rb添加下面代码
require 'win32ole'
WIN32OLE.codepage = WIN32OLE::CP_UTF8

然后一切正常,不知道以后还会不会遇到啥莫名其妙的问题。

 

PS:Ruby中ADO连接SQLServer的方式已经不再推荐使用,ADO.rb已经年久失修了,貌似有很多问题。

 

使用ODBC的方式链接SQLServer:

当然第一步要配好ODBC数据源,然后再修改database.yml:

development:
  adapter: sqlserver
  mode: ODBC  
  username: urname
  password: ***
  dsn: urdsn

 这时候Rails已经可以成功连接到SQLServer了,但是不能查询数据,查询时会报错:

wrong number of arguments (2 for 1)

需要修改 ruby\lib\ruby\1.8\delegate.rb 这个文件,

第166行和273行定义的方法需要修改为:

def respond_to?(m, include_private = false)  # :nodoc:
    return true if super
    return @_dc_obj.respond_to?(m, include_private)
end

 然后连接数据库查询不会再报错,不过查询出来的中文是GBK编码的,如果放在页面上显示,需要手动转换,比较麻烦。查看ruby\lib\ruby\gems\1.8\gems\activerecord-sqlserver-adapter-2.2.22\lib\active_record\connection_adapters\sqlserver_adapter.rb这个文件,第53行:

value.force_encoding('UTF-8') rescue value

 由于force_encoding是Ruby1.9里面新增的方法,所以在1.8下面这行代码始终返回value,而没有进行编码转换,既然知道了查询出来的结果是GBK编码的,那暂时用Iconv强制转换一下好了:

value.force_encoding('UTF-8') rescue Iconv.conv('UTF-8','GBK',value) rescue value

 至此查询显示乱码问题搞定,在对数据库进行修改操作和根据用户输入进行查询时,还得手工进行转换,再过几年Ruby社区迁移到1.9平台上后这个问题应该就会消失掉了。

 

在使用过程中发现activerecord-sqlserver-adapter (2.2.22)的分页有问题,真是多灾多难啊,继续修改上面的那个sqlserver_adapter.rb文件,第467行那一大段修改为:

if options[:limit] and options[:offset]
   sql.sub!(/ORDER BY.*$/i, '')
   sql.sub!(/SELECT/i,
                   "SELECT row_number() over( order by #{options[:order]} ) as row_num, \n")
   sql.replace("select top #{options[:limit]} * from (#{sql}) as tmp_table1 \n" +
                  "where row_num > #{options[:offset]}")
end   
 

这种修改只对于SQLServer2005以上版本有效,由于使用了order by,在查询中如果没有指定:order就会报错,继续修改will_paginate的finder.rb,在第80行args << find_options前面加上find_options[:order] ||= primary_key:

WillPaginate::Collection.create(page, per_page, total_entries) do |pager|
     count_options = options.except :page, :per_page, :total_entries, :finder
     find_options = count_options.except(:count).update(:offset => pager.offset, :limit => pager.per_page) 
     find_options[:order] ||= primary_key
     args << find_options
     # @options_from_last_find = nil
     pager.replace(send(finder, *args) { |*a| yield(*a) if block_given? })
          
    # magic counting for user convenience:
    pager.total_entries = wp_count(count_options, args, finder) unless pager.total_entries
end

 至此分页问题解决。sqlserver-adapter的作者目前正致力与解决该驱动和Rails3.0的兼容性,承诺以后会对分页语句进行修改,不知道在哪个版本里面可以解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值