rails 查询生成 oci:error 引号字符串错误终止

rails query generates oci:error quoted string incorrectly terminated

我在应用程序中有以下代码(非常遗留):

  results << User.all(
  :select => "'#{entry.name}' AS user_name, '#{entry.lastname}, #{entry.firstname}' AS user_full_name, display_name", 
  :order => "display_name")

生成以下查询我得到以下 oci 错误:

  OCIError: ORA-01756: quoted string not properly terminated: 
SELECT 'theupsstore2579' AS user_name, 'O'Brien, Perry' AS user_full_name, display_name FROM "Users" WHERE..

有什么好的方法可以解决我的问题吗?

使用 quote_string 是一个很好的方法

是的,有一个好方法。您不应该在 sql 查询中使用内插字符串,例如 "string bit #{interpolated_bit}" - 这对安全性非常不利,并会导致 SQL 注入攻击。

在这种情况下 - 因为其中一个名字包含一个 ' 字符(在姓氏 O'Brien 中 - 一旦该值被插入到你的 SQL 字符串中,它像对待任何 ' 字符一样对待它并结束字符串 - 即使在 ' 之后还有更多(即 Brien 位)

这会导致您的数据库出现语法错误。

但是 - 以这种方式使用内插字符串也会让您面临 SQL 注入 - 如果有人在他们的姓氏字段中输入 '; DROP TABLE users;(或等效项)怎么办?并且您的代码愉快地将其放入 SQL 和 运行 中吗?您使用内插字符串的方式 安全。但是 Rails 提供了 安全的替代品 - 它们是您应该始终使用的。

例如内置的 arel 方法(where select order 等)并使用经过净化的 ? 语法,而不是

results << User.all(
  :select => "'#{entry.name}' AS user_name, '#{entry.lastname}, #{entry.firstname}' AS user_full_name, display_name", 
  :order => "display_name")

你可以试试

results << User.select("'?' AS user_name, '?, ?' AS user_full_name, display_name", entry.name, entry.lastname, entry.firstname).order("display_name")

(尽管我质疑您为什么要强制所有用户使用相同的名称 - 您真的希望这些成为仅选择具有这些名称的用户的条件吗?)

我强烈建议您通读所有 Rails 指南。在这种情况下,尤其是关于如何使用 Active Record queries:

而且您可能还想阅读安全指南 - 具体来说,在这种情况下,Rails guide SQL injection section