为 orderby 生成 sql 查询的方法是不是在 tiny_tds 0.2.3 和 0.4.3 之间更改

Posted

技术标签:

【中文标题】为 orderby 生成 sql 查询的方法是不是在 tiny_tds 0.2.3 和 0.4.3 之间更改【英文标题】:Is method of generating sql query for orderby changed between tiny_tds 0.2.3 and 0.4.3为 orderby 生成 sql 查询的方法是否在 tiny_tds 0.2.3 和 0.4.3 之间更改 【发布时间】:2013-02-05 07:24:29 【问题描述】:

我有 rails 3.0.1 和 tiny_tds 0.2.3 和 activerecord-sqlserver-adapter 3.0.7,下面的查询运行良好。升级到之后 rails 3.0.20、tiny_tds 0.4.3、activerecord-sqlserver-adapter 3.0.19由于 order by 子句而停止工作。

有一个表 events,其中有一列 starts_at,其类型为 datetime

Ruby 代码:

@events = Event.where("archived = 'False' and starts_at >= ? and event_company_id in (1,2,3)", start_date).select(" distinct top(14) 转换(日期,开始时间,112)作为开始日期“)。订单(“转换(日期, 开始时间,112)")

用于生成sql查询如下:

SELECT distinct top(14) convert(date, starts_at, 112) as start_date FROM [events] WHERE(存档 = 'False' 和 starts_at >= '2013-02-04' 和 event_company_id in (1,2,3)) ORDER BY convert(date, starts_at, 112)

但是现在,正在生成的查询是:

SELECT distinct top(14) convert(date, starts_at, 112) as start_date FROM [events] WHERE(存档 = 'False' 和 starts_at >= '2013-02-05' 和 event_company_id in (1,2,3)) ORDER BY convert(date ASC, starts_at 第 112 章

请注意围绕顺序的部分:

ORDER BY convert(日期 ASC,starts_at ASC,112) ASC

而不是 ORDER BY convert(date, starts_at, 112)

因此,我收到以下错误:

TinyTds::Error: 关键字“ASC”附近的语法不正确。:

此类查询是否需要遵循一些语法更改,或者我使用的版本不正确?作为从 rails 3.0.1 迁移到 rails 3.0.20 的一部分,我不得不升级 tiny_tds 和 activerecord-sqlserver-adapter

谢谢。

【问题讨论】:

【参考方案1】:

从 3.0.8 开始,似乎有猴子修补程序试图修复 Arel 解析 order by 子句的方式: class SelectManager, method order(*expr)

如果您将字符串传递给 order 子句,它会简单地用逗号分割字符串以获得列名数组。如果您按函数排序,那么它将完全破坏 order by 子句。好消息是,您可以通过将类似这样的内容传递给 order 子句来防止这种失败的拆分:

order(
  Arel::Nodes::Ordering.new(
    Arel::Nodes::SqlLiteral.new("convert(date, starts_at, 112)")
  )
)

函数调用将按原样传递给 sql 语句生成器

【讨论】:

以上是关于为 orderby 生成 sql 查询的方法是不是在 tiny_tds 0.2.3 和 0.4.3 之间更改的主要内容,如果未能解决你的问题,请参考以下文章

有没有更好的方法来排序这个查询?

SQL语句优化

常用sql语句--DQL

sql语句优化方案

SQL 排序

为啥实体框架会生成嵌套 SQL 查询?