You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails应用使用TinyTDS连接SQL Server 2019登录失败及连接覆盖问题

问题:TinyTDS连接SQL Server 2019失败及配置覆盖问题

环境信息

使用的Gem版本:

gem 'rails', '~> 7.0.8'
gem 'activerecord-sqlserver-adapter', '7.0.7'
gem 'composite_primary_keys', '14.0.9'
gem 'tiny_tds', '2.1.7'

服务器环境:Ubuntu,FreeTDS 7.4(已尝试其他版本)

问题详情

应用可通过TinyTDS正常连接SQL Server 2016,但连接SQL Server 2019时触发登录失败错误:

/shared/bundle/ruby/3.0.0/gems/tiny_tds-2.1.7/lib/tiny_tds/client.rb:60:in connect': Login failed for user 'UN'. (TinyTds::Error)

尝试过dataserver和host/port两种连接配置方式,tsql命令及TablePlus(通过SSH转发)均可正常连接SQL Server 2019,但Rails控制台执行连接代码后验证活性时触发上述错误:

irb(main):033:2* ActiveRecord::Base.establish_connection({:adapter=>"sqlserver",
irb(main):034:2*        :encoding=>"utf8",
irb(main):035:2*        :mode=>"dblib",
irb(main):036:2*        :pool=>5,
irb(main):037:2*        :reconnect=>true,
irb(main):038:2*        :timeout=>350000,
irb(main):039:2*        :username=>"UN",
irb(main):040:2*        :password=>"aU",
irb(main):041:0>        :dataserver=> "ccsServer", :database=> "db" })
# 输出连接池信息...
irb(main):042:0> ActiveRecord::Base.connection.active?
# 触发登录失败错误

此外存在配置覆盖异常:应用原本连接同主机/端口的多个数据库,新增不同主机/端口的数据库后,用TinyTDS指定新主机/端口连接时,配置会被旧服务器的主机/端口覆盖(使用新主机/端口+旧用户名密码可成功连接),需要同时连接两个数据库并独立指定主机/端口。

已验证的情况

  • 同一服务器上TinyTDS可正常连接SQL Server 2016,环境本身无问题
  • tsql命令可通过host/port或freetds.conf配置的dataServer正常连接SQL Server 2019
  • 通过SSH连接服务器后,TablePlus用相同用户名密码可正常登录SQL Server 2019
  • 所有Gem已更新至最新版本,FreeTDS尝试过7.4及其他版本
  • FreeTDS日志显示登录失败错误(错误代码18456:Login failed for user 'UN')

可行解决方案建议

针对TinyTDS登录失败问题

  1. 显式指定TDS版本:在连接配置中添加tds_version: '7.4',确保与FreeTDS版本匹配,SQL Server 2019推荐使用TDS 7.4版本:
    ActiveRecord::Base.establish_connection({
      # 其他配置...
      tds_version: '7.4'
    })
    
  2. 检查SQL Server 2019的认证模式:确认SQL Server 2019已开启混合认证模式(SQL Server和Windows认证模式),仅Windows认证会导致SQL登录失败。
  3. 直接使用host/port而非dataserver:跳过freetds.conf配置,直接指定主机和端口,避免配置解析问题:
    ActiveRecord::Base.establish_connection({
      # 其他配置...
      host: 'ccsServer_IP',
      port: 1433, # 或SQL Server实际端口
      dataserver: nil # 清空dataserver配置
    })
    
  4. 验证密码特殊字符转义:如果密码包含特殊字符(如@、!等),确保在Ruby配置中正确转义,或使用环境变量传递密码避免解析错误。

针对连接配置被覆盖问题

  1. 使用独立的数据库连接类:为新数据库创建独立的ActiveRecord模型基类,避免共享ActiveRecord::Base的连接池:
    class NewDbBase < ActiveRecord::Base
      self.abstract_class = true
      establish_connection({
        adapter: "sqlserver",
        encoding: "utf8",
        mode: "dblib",
        pool: 5,
        reconnect: true,
        timeout: 350000,
        username: "NEW_UN",
        password: "NEW_PW",
        host: "new_server_ip",
        port: 1433,
        database: "new_db",
        tds_version: '7.4'
      })
    end
    
    # 新数据库的模型继承自NewDbBase
    class NewDbModel < NewDbBase
      self.table_name = 'some_table'
    end
    
  2. 配置database.yml多数据库连接:在config/database.yml中明确配置两个数据库,通过establish_connection指定不同的配置项:
    production:
      primary:
        adapter: sqlserver
        encoding: utf8
        mode: dblib
        pool: 5
        reconnect: true
        timeout: 350000
        username: UN
        password: aU
        dataserver: ccsServer
        database: db
        tds_version: '7.4'
      new_db:
        adapter: sqlserver
        encoding: utf8
        mode: dblib
        pool: 5
        reconnect: true
        timeout: 350000
        username: NEW_UN
        password: NEW_PW
        host: new_server_ip
        port: 1433
        database: new_db
        tds_version: '7.4'
    
    然后在模型中指定连接:
    class OldDbModel < ActiveRecord::Base
      connects_to database: { writing: :primary, reading: :primary }
    end
    
    class NewDbModel < ActiveRecord::Base
      self.abstract_class = true
      connects_to database: { writing: :new_db, reading: :new_db }
    end
    
  3. 清除连接池缓存:在切换数据库连接前,显式清除旧连接池,避免配置缓存:
    ActiveRecord::Base.connection_pool.disconnect!
    ActiveRecord::Base.clear_all_connections!
    # 再建立新连接
    

内容的提问来源于stack exchange,提问作者madav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:45:54