- 浏览: 326901 次
- 来自: 上海交通大学软件学院
文章分类
最新评论
-
whatable:
楼主写得很好!!
小试org.eclipse.jface.dialogs.TitleAreaDialog -
yeshaoting:
顶~~顶~~顶~~
另一只眼看Eclipse,所谓的开源 -
wenhai_zhang:
好,不错。发贴留地址
小试org.eclipse.jface.dialogs.TitleAreaDialog -
ss1:
具体点,我还是不会啊
在Liferay Portal中使用DWR -
rubynroll:
robbin 写道每次当我想操起ruby写rake file的 ...
我的第一关rake文件
手头一个项目有这样一个需求,数据库中有一张学生表students,其中每个学生都有自己的生源地(come_from),用户希望能够随机的选择一些学生出来,但是要保证每个生源地的学生都有。
我的开发环境是RoR + MySql,简单考虑了一下后,第一个能想到的方法是在rails中生成随机数,然后用offset来得到随机的学生。但是这样做比较麻烦,性能也会很差,因为首先要知道每个生源地下有多少学生,不然的话,生成的随机数可能会过大。
排除了这个选择,于是考虑是否可以在sql级别实现。去查了查MySql的manual,发现有个然数RAND()可以用来生成0到1之间的随机浮点数,感觉可以用这个来做,马上试试看。
注意,这里的随机方式与一般的想法不同。一般的想法是生成一个随机数作为offset,然后去找在offset上的数据项;而这里的做法是随机的对数据项进行排序(即shuffle),然后获得第一个。
以上sql多运行了几次下来,确实随机返回不同的学生,离目标近了一步,好事情。剩下来就是如何随机的在所有生源地上选择一个学生,如果学生个数不够,还要再随机选择剩余学生。出于性能考虑,我打算用stored procedure:
以上代码还是挺简单的,就是先找到所有的生源地,然后循环,以每个生源地作为条件随机出一个学生来。一开始的时候我还想传入一个参数,代表想要得到的学生个数,比如50、100的。因为这个个数通常比生源地个数要多,所以后面还应该随机取出一些学生来。但是我不知道这个sql应该怎么写,因为假设我们可以得到变量student_number代表想要的学生个数、come_from_number代表生源地的个数,那么sql语句应该差不多如下:
但是其中加粗的部分,sql自然是不认识的,也就是说LIMIT后面不能接变量,所以我也不知道该怎么办,所幸就拿到stored procedure外面来做了。
以上可以说是实现了MySql端的东东,那么rails方面呢?一开始我尝试使用
结果报错说:ActiveRecord::StatementInvalid: Mysql::Error: PROCEDURE vc.testsp can’t return a result set in the given context.
到网上搜了一下,发现rails的wiki里面就有一篇讲怎么使用sp的,于是就按部就班的做了,不过网上的教程有点儿过时了,这里稍微做一个介绍:
[list=1]先保证自己装的是MySql 5.0+版本。
安装native MySql Connector:gem install mysql。
修改rails中的mysql_adapter.rb,文件在$RUBY_ROOT/lib/ruby/gems/1.8/gems/activerecord-$VERSION/lib/active_record/connection_adapters中,具体修改如下:
==>
这是因为sp有可能会返回多个结果集(说白了就是有多个SELECT,像我的sp就是这样),而rails默认的连接设置不支持这个,就会报错,而且即使只返回一个结果集,也会报一样的错误。65536代表的是MySql选项CLIENT_MULTI_STATEMENTS,这样一来就知道怎么回事儿了。为rails添加一个调用sp的方法:
这个方法应该添加在ConnectionAdapters::MysqlColumn中(仍然在mysql_adapter.rb中),可以加到SCHEMA STATEMENTS段。最后在Student.rb里面加入调用sp的方法:
[/list]
写了这么多,以为可以万事大吉了,谁知道调用下来,却报了下面这个错误:Commands out of sync; you can't run this command now.这下可不知道怎么办了,搜了一阵子也没有答案。我猜想可能与多结果集有关,于是写了一个单结果集的sp来调用,果然就没有问题。看来我的这个功能还真不能在sql里面做咧,于是只好全部转到ruby里面,不过还好有MySql的RAND()函数,性能不是太差,而且我数据库里面大概就2w数据,不多。
我的开发环境是RoR + MySql,简单考虑了一下后,第一个能想到的方法是在rails中生成随机数,然后用offset来得到随机的学生。但是这样做比较麻烦,性能也会很差,因为首先要知道每个生源地下有多少学生,不然的话,生成的随机数可能会过大。
排除了这个选择,于是考虑是否可以在sql级别实现。去查了查MySql的manual,发现有个然数RAND()可以用来生成0到1之间的随机浮点数,感觉可以用这个来做,马上试试看。
SELECT * FROM students WHERE come_from = '上海市' ORDER BY RAND() LIMIT 1;
注意,这里的随机方式与一般的想法不同。一般的想法是生成一个随机数作为offset,然后去找在offset上的数据项;而这里的做法是随机的对数据项进行排序(即shuffle),然后获得第一个。
以上sql多运行了几次下来,确实随机返回不同的学生,离目标近了一步,好事情。剩下来就是如何随机的在所有生源地上选择一个学生,如果学生个数不够,还要再随机选择剩余学生。出于性能考虑,我打算用stored procedure:
CREATE DEFINER=`root`@`%` PROCEDURE `random_students`() BEGIN DECLARE done INT DEFAULT 0; DECLARE var_come_from VARCHAR(255); DECLARE come_from_cursor CURSOR FOR SELECT come_from FROM eva_development.students GROUP BY come_from; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; OPEN come_from_cursor; REPEAT FETCH come_from_cursor INTO var_come_from; SELECT * FROM eva_development.students where come_from = var_come_from order by rand() limit 1; UNTIL done END REPEAT; CLOSE come_from_cursor; END
以上代码还是挺简单的,就是先找到所有的生源地,然后循环,以每个生源地作为条件随机出一个学生来。一开始的时候我还想传入一个参数,代表想要得到的学生个数,比如50、100的。因为这个个数通常比生源地个数要多,所以后面还应该随机取出一些学生来。但是我不知道这个sql应该怎么写,因为假设我们可以得到变量student_number代表想要的学生个数、come_from_number代表生源地的个数,那么sql语句应该差不多如下:
SELECT * FROM students LIMIT [b](student_number - come_from_number)[/b];
但是其中加粗的部分,sql自然是不认识的,也就是说LIMIT后面不能接变量,所以我也不知道该怎么办,所幸就拿到stored procedure外面来做了。
以上可以说是实现了MySql端的东东,那么rails方面呢?一开始我尝试使用
Student.find_by_sql('call random_students()')
结果报错说:ActiveRecord::StatementInvalid: Mysql::Error: PROCEDURE vc.testsp can’t return a result set in the given context.
到网上搜了一下,发现rails的wiki里面就有一篇讲怎么使用sp的,于是就按部就班的做了,不过网上的教程有点儿过时了,这里稍微做一个介绍:
[list=1]
ConnectionAdapters::MysqlAdapter.new(mysql, logger, [host, username, password, database, port, socket], config)
==>
ConnectionAdapters::MysqlAdapter.new(mysql, logger, [host, username, password, database, port, socket, 65536], config)
这是因为sp有可能会返回多个结果集(说白了就是有多个SELECT,像我的sp就是这样),而rails默认的连接设置不支持这个,就会报错,而且即使只返回一个结果集,也会报一样的错误。65536代表的是MySql选项CLIENT_MULTI_STATEMENTS,这样一来就知道怎么回事儿了。
def select_sp(sql, name = nil) rows = select(sql, name = nil) while (@connection.more_results?()) @connection.next_result() end return rows end
这个方法应该添加在ConnectionAdapters::MysqlColumn中(仍然在mysql_adapter.rb中),可以加到SCHEMA STATEMENTS段。
def self.random_select(student_number) students = connection.select_sp('call random_students') students << find_by_sql(['select * from students order by rand() limit ?', student_number - students.length]) unless students.length >= student_number students.flatten[0, student_number] end
[/list]
写了这么多,以为可以万事大吉了,谁知道调用下来,却报了下面这个错误:Commands out of sync; you can't run this command now.这下可不知道怎么办了,搜了一阵子也没有答案。我猜想可能与多结果集有关,于是写了一个单结果集的sp来调用,果然就没有问题。看来我的这个功能还真不能在sql里面做咧,于是只好全部转到ruby里面,不过还好有MySql的RAND()函数,性能不是太差,而且我数据库里面大概就2w数据,不多。
def self.random_select(number = 50) result = [] students = Student.find_by_sql('select come_from from students group by come_from') students.each do |student| result << Student.find_by_sql(['select * from students where come_from = ? order by rand() limit 1', student.come_from]) end result << Student.find_by_sql(['select * from students order by rand() limit ?', number - students.length]) unless students.length >= number result.flatten[0, number] end
评论
2 楼
bernieyoo
2007-10-18
我看了一下你的Store Procedure,你所谓的多个结果集其实是可以合并到一个结果集里的。可以用如下几种方式:
1、在循环中不要直接执行SQL语句,而是拼接SQL字符串,类似这样的:
最后一次执行:
2、你在循环中取到的结果集的结构是一样的,那可以考虑将每次的结果集存入一个临时表,最后从临时表取出全部结果,类似这样:
我以上都是用SQL Server的语法写的,因为mysql不熟,但应该有类似的方法的。
另外,我调用Store Procedure是用DBI来实现的,这样可以实现对多个结果集的处理。但你这个应该是不需要的。
转变一下编程思路,会有意想不到的结果。
1、在循环中不要直接执行SQL语句,而是拼接SQL字符串,类似这样的:
select * from .... Union Select * from ...
最后一次执行:
exec(@sql)
2、你在循环中取到的结果集的结构是一样的,那可以考虑将每次的结果集存入一个临时表,最后从临时表取出全部结果,类似这样:
Create Table #temp(....) While insert into #temp select * from .... ... ... Select * from #temp
我以上都是用SQL Server的语法写的,因为mysql不熟,但应该有类似的方法的。
另外,我调用Store Procedure是用DBI来实现的,这样可以实现对多个结果集的处理。但你这个应该是不需要的。
转变一下编程思路,会有意想不到的结果。
1 楼
ivice
2007-10-06
我以前用mssql和vb写程序的时候,可以设置set nocount on 在最后一个要返回结果的select前面 可以加一个set nocount off。
这样就不会出错,mysql和rails不知道有没有这种用法。
这样就不会出错,mysql和rails不知道有没有这种用法。
发表评论
-
批量下载railscasts上视频的ruby脚本
2008-07-14 12:00 2743Railscasts 上面的视频已经出到117集了,很早就想把 ... -
在Leopard上使用NetBeans Ruby IDE
2008-01-17 10:57 1969本来像NetBeans这样到东东,应该是装上就可以用到。但是在 ... -
在Leopard上手动安装RMagick
2008-01-17 10:44 2032这几天刚刚给自己的小白安装了Leopard,开始迫不及待的把开 ... -
使用ruby生成zip文件
2007-10-23 17:28 6114首先安装rubyzip: gem install rubyz ... -
在habtm上使用polymorphic关联
2007-10-05 15:19 2676我们知道,在rails中,ha ... -
我的第一关rake文件
2007-09-23 17:10 4125早就想找个机会写写rake文件,但是接触到的项目都不怎么需要, ... -
ferret啊,为你欢喜为你忧。
2007-08-09 18:05 2501非常非常奇怪的问题。一开始在mac下面用standard ra ... -
在Mac上安装RMagick?别以为有了Locomotive就万事大吉啦~
2007-08-02 09:30 2690我或多或少算是一个Mac ... -
在controller里面怎么escape html内容?
2007-07-24 10:24 3580在view里面可以用h来escape html内容。那在con ... -
ActiveRecord中表关联的一个问题,belongs_to和has_many不是一一对应的情况。
2007-07-19 18:15 4025一个挺有意思的问题,想了半天没有解决办法。 情景是这样的:系 ... -
Rails routes mapping的一个奇怪的问题。顺便讨论一下如何做RESTful的paginate。
2007-07-18 09:33 3093大家可以试验一下,在我的开发环境中会出现这个问题,不知道是不是 ... -
[讨论]部署Rails的最佳方案是什么?
2007-07-06 13:46 13567从来没真正部署过一个production级别的rails应用, ... -
Rails中使用REST,登录相关的问题,如何获得当前正在处理的url?
2007-07-03 16:39 3917如果整个routes是使用传统的mvc方式实现的话,我们可以简 ... -
Eclipse 3.3携Europa正式发布了
2007-07-01 12:57 33766刚刚逛了一圈论坛,竟 ... -
在apple上使用ruby的郁闷事儿
2007-06-23 19:49 2033安装了那个Locomotive,还有iTerm,还有Textm ... -
在ubuntu下安装ruby需要注意的事情
2007-06-23 19:41 4963这里说的是通过apt-get安装ruby,自己编译的情况就免了 ... -
基于model动态地ComboBox为生成options
2007-06-17 16:17 2310在使用RoR创建form时,很多时候需要基于model之间的关 ... -
Meta-Programming in Ruby: 动态生成class,并添加attribute和method。
2006-12-17 16:10 4915Ruby的动态语言特性和强大的meta-programming ...
相关推荐
由于在Windows上直接安装可能会遇到问题,可以尝试使用预编译的二进制版本,或者在命令行中运行`gem install mysql2 --platform=ruby -- --with-mysql-dir="C:\path\to\mysql\installation"`,其中"C:\path\to\mysql...
然而,有时在尝试连接Rails应用到MySQL数据库时,可能会遇到一些问题。本篇文章将深入探讨这些常见问题及其解决方案。 首先,Rails与MySQL的连接问题可能源于配置不正确。在`config/database.yml`文件中,你需要...
在开发基于Web的应用程序时,Ruby on Rails(简称Rails)框架和MySQL数据库的结合是常见的选择。本文将详细介绍如何在Windows环境下配置Ruby on Rails以支持Rails 2.3.5及以上版本,并与MySQL进行无缝对接。 首先,...
在安装和配置 Ruby on Rails 和 MySQL 数据库的过程中,可能会遇到一些问题。例如,在创建 POSTS 应用时可能会遇到问题,创建数据后数据库中有数据,但是到 Listing posts 界面无法查看,总是报错。解决方法是下载 ...
当在Ruby on Rails项目中使用MySQL作为数据存储时,这两个技术的结合提供了强大的后端支持。 在Rails中集成MySQL,你需要安装特定的数据库适配器,即`mysql2` gem。这个gem允许Rails与MySQL数据库进行通信,处理SQL...
docker-rails6-mysql8 启动Rails设置 跑新轨道 $ docker-compose run web rails new . --force --no-deps --database=mysql --skip-test --webpacker docker镜像构建 $ docker-compose build 编辑database.yml ...
标题 "在Rails中使用RSpec生产CHM文档" 暗示了这个话题是关于如何在Ruby on Rails(简称Rails)框架中使用RSpec测试工具来创建帮助文档,特别是以CHM(Microsoft Compiled HTML Help)格式。CHM文件是一种常见的...
在Ubuntu 11.04环境中,安装MySQL数据库是部署Ruby on Rails应用的重要步骤之一。首先,通过打开终端并执行以下命令进行安装: ```bash sudo apt-get install mysql-server ``` 在安装过程中,系统会提示输入MySQL...
在Ruby on Rails中文指南中,你将全面学习到如何利用这个强大的框架来构建动态的、数据驱动的Web应用程序。 首先,让我们深入理解Rails的核心概念: 1. **路由(Routes)**:Rails的路由系统是应用程序的导航蓝图...
在Rails框架中处理文件上传时,经常会遇到一个问题,那就是当用户尝试上传包含中文名称的文件时,文件名可能会出现乱码。这个问题主要是由于字符编码不兼容导致的。Rails默认使用UTF-8编码,但文件系统或者某些外部...
在Rails应用中,当面临大数据表的处理时,MySQL的分区表是一个实用的优化策略,可以显著提升查询性能。MySQL的分区表特性允许我们将一张大表分割成多个小表,以便于管理和加速查询。在本例中,针对一个名为diet_...
安装过程中,遵循提示进行,确保选择自定义安装并勾选Rails相关的插件,以便在Aptana中获得对Rails的全面支持。 安装完成后,打开Aptana Studio,创建一个新的Rails项目。在“File”菜单中选择“New”然后点击...
1.安装gem,进入gem文件夹,里面有个setup文件,直接双击就行了。 2.进入rails目录使用gem命令安装(这一步必须要上...3.复制libmySQL.dll到ruby的安装目录的bin文件夹下,然后使用gem安装mysql-2.7.3-x86-mswin32.gem.
在Rails开发中,为了增强用户体验,常常需要使用JavaScript来处理日期选择和管理。这篇博客“rails中使用javascript日期控件”探讨的就是如何在Rails应用中集成JavaScript日期控件,特别是通过一个名为WebCalendar....
5. **Gemfile与Bundler**:Rails项目通常使用Gemfile来管理依赖库,Bundler工具则用于安装和管理这些依赖,确保在不同环境下项目的运行一致性。 6. **Scaffolding**:Rails提供了快速生成基本CRUD(Create, Read, ...
在Ruby on Rails中,开发者可以快速构建功能丰富的动态网站,因为它提供了大量的内置功能和库,如数据库连接、ORM(对象关系映射)系统ActiveRecord、模板引擎ActionView以及路由系统ActionController等。...
rails-assets, 在 Rails 中,资产管理的解决 Rails 资产 Bundler 到 Bower 代理本自述文件涉及项目的开发方面。 访问站点了解如何在你的应用程序中使用 Rails 资产。 插件开发设置git clone git@github.com:tenex/r
此外,书中还介绍了一些Rails中的高级概念,如Strong Parameters(强参数),它在Rails 4.0版本中引入,用于解决之前版本中的参数篡改问题,从而帮助开发者安全地处理外部提交的数据。 通过一系列的教学内容,包括...
在Rails项目中安装Mongrel通常通过RubyGems进行,这是一个Ruby的包管理器。首先确保RubyGems已经安装,然后在命令行执行以下命令: ```bash gem install mongrel ``` 安装完成后,可以通过`mongrel_rails`命令来...
– c:/ruby/lib/ruby/gems/1.8/gems/mysql-2.7.3-x86-mswin32/ext/mysql.so 实际上是找不到连接所需的dll文件:libmySQL.dll 在mysql安装目录下的bin目录下将此文件复制到ruby的bin目录下即可解决此问题. ...