【问题标题】:Check if input string conforms with DB collation检查输入字符串是否符合数据库排序规则
【发布时间】:2016-09-21 07:33:08
【问题描述】:

由于我们的电子邮件服务的限制,我们有一个带有电子邮件字段的表格 - 排序规则latin1_swedish_ci

当有新用户到达时检查此表以查看他是否已订阅。

用户的电子邮件中出现了对该特定排序规则无效的字符。比如hsıasdf@test.com


是否有可能在保存之前确定一个字符串是否会 遵守数据库的排序规则?

我是否可以在任何数据库触发器之前检查 保存/创建/查找;如果包含此特定电子邮件的条目将 同意整理?也许是一些正则表达式?

【问题讨论】:

  • Rails 默认集合设置为utf8_general_ci。是否要将整个 rails 应用程序更改为使用 latin_swedish_ci
  • @Coderhs 整个应用程序已经使用了latin_swedish_ci。如果不支持输入值,我只是不想运行数据库查询
  • 电子邮件系统是否与您的 Rails 应用程序共享数据库?谴责你的整个申请 latin_swedish_ci 似乎是一个非常苛刻的解决方案。
  • 通过执行这个查询作为测试函数并在mysql抛出错误时返回false不是一个有效的方法吗?
  • @Solarflare 可以,但这个问题不仅限于此表。有多个地方的排序规则不匹配会引发错误。我可以将所有这些 sn-ps 包装在救援块中,但如果有更优雅的方法来做到这一点..

标签: mysql ruby-on-rails collation


【解决方案1】:

试试下面的查询。它可能对你有帮助。

select * from user_subscription where email=cast('hsıasdf@test.com' as char CHARSET latin1);

【讨论】:

    【解决方案2】:
    RoR: application_controller.rb
    
      def configure_charsets
        response.headers["Content-Type"] = "text/html; charset=utf-8"
        suppress(ActiveRecord::StatementInvalid) do
          ActiveRecord::Base.connection.execute 'SET NAMES UTF8'
        end   end
    

    您应该使用 utf8(或 utf8mb4),而不是非常有限的 latin1(仅处理西欧)。

    ALTER TABLE user_subscriptions
        CONVERT TO utf8;
    

    (任何其他表格同上)。

    你的标题谈到了检查。但我认为,当您使用相同的CHARACTER SET 获取所有内容时,就不需要进行任何“检查”了。

    【讨论】:

      【解决方案3】:

      在 Ruby 中,您可以使用String#encode 来测试常见编码之间的字符串转换。

      但是这无济于事,因为您想测试 MySQL 特定的排序规则。

      你可以做的是使用transaction:

      User.transaction do
        if User.create!(email: 'hsıasdf@test.com')
          puts "yup its valid"
          raise ActiveRecord::Rollback
        end
      end
      

      但是它并不是非常有效。如果您希望它在保存之前运行,您可以使用自定义验证。

      如果可能的话,我会使用 MySQL 标准 utfutf8_general_ci,并且只在需要与电子邮件系统交互的应用程序边界进行转换。使用非 UTF-8 编码会给您带来很多麻烦,从长远来看,如果更改了错误的电子邮件系统,可能会非常不利。

      您可以通过以下方式即时选择整理:

      SELECT users.email COLLATE latin1_swedish_ci AS users.collated_email
      FROM users
      

      【讨论】:

      • 使用 Ruby 1.8.7 - 所以不使用编码。更改排序规则将是一个问题,因为拉丁语目前是我们的默认排序规则。我会避免修改整个数据库。
      • 您需要尽快升级您的 Ruby。 1.8.7 早在 2013 年就退役了,有很多安全漏洞,比 2.x 慢很多。
      • 是的,我知道。事实上,我们正在为 Ruby 和 Rails 升级做准备,并将在几周内完成。这个问题仍需单独处理。
      • 我会先检查错误是否是由于 ActiveRecord 使用了错误的排序规则 - 尝试 ActiveRecord::Base.connection.collationmysql> show variables like 'collation%';。然后尝试使用事务。
      猜你喜欢
      • 1970-01-01
      • 2017-01-01
      • 2011-01-21
      • 1970-01-01
      • 1970-01-01
      • 2016-03-03
      • 2011-07-22
      相关资源
      最近更新 更多