当前位置: 首页 > 面试题库 >

在Rails 3应用程序中使用原始SQL查询?

严心水
2023-03-14
问题内容

我正在将旧数据库迁移到我的Rails应用程序(3.2.3)中。原始数据库带有相当多的长SQL查询报表。就目前而言,我想使用Rails应用程序中的sql查询,然后(在时间允许的情况下)将sql查询一一交换为“适当的”
Rails查询。

我有一个临床模型,控制器具有以下代码:

 @clinical_income_by_year = Clinical.find_all_by_sql(SELECT date_format(c.transactiondate,'%Y') as Year, 
                                                 date_format(c.transactiondate,'%b') as Month,
                                                 sum(c.LineBalance) as "Income"
                                                 FROM clinical c
                                                 WHERE c.Payments = 0 AND c.LineBalance <> 0
                                                 AND c.analysiscode <> 213
                                                 GROUP BY c.MonthYear;)

但是,当我运行该代码时,会遇到一些与格式有关的错误。

Started GET "/clinicals" for 127.0.0.1 at 2012-04-29 18:00:45 +0100

SyntaxError (/Users/dannymcclelland/Projects/premvet/app/controllers/clinicals_controller.rb:6: syntax error, unexpected tIDENTIFIER, expecting ')'
...rmat(c.transactiondate,'%Y') as Year, 
...                               ^
/Users/dannymcclelland/Projects/premvet/app/controllers/clinicals_controller.rb:7: syntax error, unexpected tIDENTIFIER, expecting keyword_end
...rmat(c.transactiondate,'%b') as Month,
...                               ^
/Users/dannymcclelland/Projects/premvet/app/controllers/clinicals_controller.rb:8: syntax error, unexpected tIDENTIFIER, expecting keyword_end
...          sum(c.LineBalance) as "Income"
...                               ^
/Users/dannymcclelland/Projects/premvet/app/controllers/clinicals_controller.rb:10: syntax error, unexpected tCONSTANT, expecting keyword_end
...       WHERE c.Payments = 0 AND c.LineBalance <> 0
...                               ^
/Users/dannymcclelland/Projects/premvet/app/controllers/clinicals_controller.rb:10: syntax error, unexpected '>'
...yments = 0 AND c.LineBalance <> 0
...                               ^
/Users/dannymcclelland/Projects/premvet/app/controllers/clinicals_controller.rb:11: syntax error, unexpected '>'
...          AND c.analysiscode <> 213
...                               ^

在将它导入控制器之前,我应该对sql查询做些什么?尽管查询可能有问题(它是在很早以前编写的),但是当直接在数据库中运行时,它确实可以按预期工作。它返回一个像这样的数组:

----------------------------------------------
|  Year      |    Month     |     Income     |
----------------------------------------------
----------------------------------------------
|  2012      |    January   |   20,000       |
|  2012      |    February  |   20,000       |
|  2012      |    March     |   20,000       |
|  2012      |    April     |   20,000       |
----------------------------------------------
etc..

任何帮助,建议或一般指示将不胜感激!

我正在阅读http://guides.rubyonrails.org/active_record_querying.html,尝试将sql查询转换为正确的Rails查询。

到目前为止,我已经匹配了倒数第二行:

AND c.analysiscode <> 213

@clinical_income_by_year = Clinical.where("AnalysisCode != 213")

宝贝的步骤!

更新

感谢Rails指南站点,我现在已经对筛选进行了排序,但是我被困在sql查询的分组和求和部分中。到目前为止,我有以下内容:

@clinical_income_by_year = Clinical.where("AnalysisCode != 213 AND Payments != 0 AND LineBalance != 0").page(params[:page]).per_page(15)

我正在努力构建以下两行sql查询:

sum(c.LineBalance) as "Income"

GROUP BY c.MonthYear;)

我的视图代码如下所示:

<% @clinical_income_by_year.each do |clinical| %>
  <tr>
    <td><%= clinical.TransactionDate.strftime("%Y") %></td>
    <td><%= clinical.TransactionDate.strftime("%B") %></td>
    <td><%= Clinical.sum(:LineBalance) %></td>
  </tr>    
  <% end %>
</table>
  <%= will_paginate @clinical_income_by_year %>

问题答案:

Ruby解析器不理解SQL,您需要使用一个字符串

@clinical_income_by_year = Clinical.find_by_sql(%q{ ... })

我建议为此使用%q%Q(如果需要插值),这样就不必担心嵌入的引号了。您还应该将其移入模型的类方法中,以使您的控制器不必担心与他们无关的事情,这也将使您易于访问connection.quote并成为朋友,以便您可以正确使用字符串插值:

find_by_sql(%Q{
    select ...
    from ...
    where x = #{connection.quote(some_string)}
})

另外,SQL中的分号:

GROUP BY c.MonthYear;})

没必要 一些数据库会允许它通过,但是无论如何您都应该摆脱它。

取决于您的数据库,标识符(表名,列名等)应不区分大小写(除非某些可恶的人在创建它们时将其引用),因此您可以使用小写的列名使内容适合Rails更好。

还要注意,有些数据库不喜欢GROUP BY,因为SELECT中的列没有聚合或分组,因此c.transactiondate每个组使用哪个列含糊不清。

查询的更多“ Railsy”版本将如下所示:

@c = Clinical.select(%q{date_format(transactiondate, '%Y') as year, date_format(transactiondate, '%b') as month, sum(LineBalance) as income})
             .where(:payments => 0)
             .where('linebalance <> ?', 0)
             .where('analysiscode <> ?', 213)
             .group(:monthyear)

然后,您可以执行以下操作:

@c.each do |c|
    puts c.year
    puts c.month
    puts c.income
end

访问结果。您还可以通过将日期处理推入Ruby来简化一点:

@c = Clinical.select(%q{c.transactiondate, sum(c.LineBalance) as income})
             .where(:payments => 0)
             .where('linebalance <> ?', 0)
             .where('analysiscode <> ?', 213)
             .group(:monthyear)

然后c.transactiondate用Ruby拆开,而不是调用c.yearand c.month



 类似资料:
  • 如何在SQLAlchemy中执行原始SQL? 我有一个在flask上运行的python web应用程序,它通过SQLAlchemy与数据库接口。 我需要一种方法来运行原始SQL。查询涉及多个表连接以及内联视图。 我试过: 但我总是会遇到网关错误。

  • 在模型查询API不够用的情况下,你可以使用原始的sql语句。django提供两种方法使用原始sql进行查询:一种是使用Manager.raw()方法,进行原始查询并返回模型实例;另一种是完全避开模型层,直接执行自定义的sql语句。 警告 编写原始的sql语句时,应该格外小心。每次使用的时候,都要确保转义了参数中的任何控制字符,以防受到sql注入攻击。更多信息请参阅防止sql注入。 进行原始查询 r

  • 问题内容: 如何在SQLAlchemy中执行原始SQL? 我有一个在烧瓶上运行的python Web应用程序,并通过SQLAlchemy连接到数据库。 我需要一种运行原始SQL的方法。该查询涉及多个表联接以及内联视图。 我试过了: 但是我不断收到网关错误。 问题答案: 你有没有尝试过: 要么:

  • 我在这里发帖寻求帮助定位导致React Native Android应用程序崩溃的问题。该应用程序使用React Native导航。我无法找出导致应用程序崩溃的错误。它在开始加载主屏幕时崩溃。 我删除了多重索引。自第一条评论后安装,但仍会发生崩溃。 更新:问题根本不是崩溃,而是一些较旧的C代码的混合,这些代码在主活动停止时退出应用程序。感谢所有提示。 很抱歉发布了长日志输出!

  • 当某些浏览器请求我们的网站但指定HTTP头时,我们已经看到了Airbrake异常(看起来大多数是移动的)。经过一系列研究,似乎大多数面向消费者的应用程序都忽略了接受HTTP头和发送HTML,我们之前通过将其添加到文件中来修复这一问题 但后来我们的电子邮件开始以纯文本发送,我相信这是因为我们正在重新定义的工作方式。是否有更好的修复方法,使我们在有人发送头时仍然发送HTML? 编辑:我忘了说,这是我运

  • 我的应用程序中的查询有问题。这是执行查询的查询方法: 这是错误: 在我发现的痕迹中: 原因:java。lang.IllegalArgumentException:在EntityManager中创建查询时发生异常:异常描述:语法错误解析[SELECT*FROM PRODUCT WHERE CATEGORY='Humano'。[22,22]select语句必须有FROM子句。[7,7]算术表达式中缺少