如何使用ActiveRecord :: ConnectionAdapters在Rails中使用动态绑定准备原始sql语句?

时间:2013-04-20 20:12:45

标签: ruby-on-rails-3.2 rails-activerecord

我使用MySQL DB和MySQL2作为适配器。

我想在Rails中执行自定义sql语句。

我需要一个允许像PHP一样准备sql语句的方法,如下所示:

stmt = prepare("INSERT INTO tab (col1, col2) VALUES (?, ?)", ["foo", "bar"])

但我发现,ActiveRecord和MySQL2都没有这样的方法。

但我发现ActiveRecord::ConnectionAdapters::AbstractAdapter中有几种exec_*方法,我认为它们完全适用于我的任务,但不知道如何使用它们,它们的API文档只有很少的信息:< / p>

  

exec_insert(sql,name,binds)

     

执行insert sql语句   使用绑定作为绑定替换的此连接的上下文。   name是与执行的sql语句一起记录的。

我已经厌倦了这个

sql = "INSERT INTO tab (col1, col2) VALUES (?, ?)"
r = ActiveRecord::Base.connection().exec_insert(sql, "someName", [10, "foo"])
puts r

但得到了一个错误:

`query': Mysql2::Error: You have an error in your SQL syntax; check the manual 
that corresponds to your MySQL server version for the right syntax to use near '?, ?)'

那么如何使用这些方法呢?什么是name属性?什么是bind参数的类型?如何编写sql-statement,放什么而不是?

UPD:

我已经编写了prepare方法在Rails中使用。 See in github

2 个答案:

答案 0 :(得分:0)

我不建议您使用exec_insert,因为它是一种“内部”方法,将来很容易发生变化。

Rails方法如下:要么使用AR好东西(即你绕过SQL),要么使用纯SQL,将两者混合起来不是一个实用的选择。

Bindings(exec_inser的第3个参数)是很棒的工具,它们允许您动态检查传递给数据库列的数据库的值,但是它们的使用没有记录,因为您不应该使用它们。

1)手动构建SQL查询

sql = "INSERT INTO tab (col1, col2) VALUES (10, 'foo')"

2)将其解压到数据库

r = ActiveRecord::Base.connection.execute(sql)

3)检查结果。这是特定于数据库适配器的。

干杯,

P.S。不要忘记created_atupdated_at columns,将其设置为'DateTime.now'

答案 1 :(得分:0)

回答得太迟了,所有的滑轨都升级了,但这也许正是您想要的-

ActiveRecord::Base.connection().exec_query('INSERT INTO table(column1, column2) VALUES($1, $2)', 'someName', [[nil, 10], [nil, 'column2Value']])

请注意,我已使用并测试了$ 1,$ 2 仅用于Postgres ,因为这是在postgres中准备查询的惯例。

对于MySql和其他数据库,可能有所不同。对于Mysql,我认为应该是?而不是$ 1,$ 2等