将数组插入到PostgreSQL映射准备语句中

3
我有这段代码:
require 'pg'
a = ["bla","foo","bar","test","wow"]

begin
con = PG.connect :dbname => 'base', :user => 'thatsme'

a.map do |e|
    con.prepare('statement1','INSERT INTO keywords (keyword, created_at, updated_at) VALUES ($1, $2, $3)')
    con.exec_params('statement1', ["#{e}", '2017-01-01 07:29:33.096192', '2017-01-01 07:29:33.096192' ])
end

这会导致一个错误,错误信息为

ERROR:  syntax error at or near "statement1"

我不理解,我漏掉了什么...


1
似乎应该使用双引号进行字符串插值: con.exec_params('statement1', ["#{e}", ... - Ilya
没错,谢谢!但这并不能让错误消失。我仍然有“ERROR: syntax error at or near 'statement1'”。 - thiebo
"#{e}" 这样的东西令人担忧,看起来像是一种仪式性编程。如果你想确保 e 是一个字符串,请使用 e.to_s,尽管驱动程序通常会自动进行此转换。此外,不要直接使用底层驱动程序,尝试使用一些具有抽象化程度的工具,例如 Sequel - tadman
无论我是使用 con.exec_params('statement1', [e.to_s, ... 还是 "#{e.so_s}", ....",它仍然会导致相同的错误。 - thiebo
我想说的是去掉无用的引号。如果 e 是一个字符串,那么 "#{e}" 只会分散你注意力,让你无法专注于自己想要做的事情。 - tadman
2个回答

2
"

exec_params方法不接受准备好的语句名称,这不是支持的参数。

您可能打算使用send_query_prepared方法,该方法具有该参数。

这是您代码的重构版本:

"
a.each_with_index do |r, i|
  con.prepare("statement_#{i}","INSERT INTO keywords (keyword, created_at, updated_at) VALUES ($1, $2, $3)")
  con.exec_prepared("statement_#{i}", [r, '2017-01-01 07:29:33.096192', '2017-01-01 07:29:33.096192' ])
end

如果您不关心结果,应该使用each而不是map,因为map会创建一个重写条目的临时数组。此外,each_with_index可以避免手动操作i

0

这是解决方案(如果有帮助到某人):

con = PG.connect :dbname => 'base', :user => 'thatsme'
i = 1;

a.map do |r|
    con.prepare("statement_#{i}","INSERT INTO keywords (keyword, created_at, updated_at) VALUES ($1, $2, $3)")
    con.exec_prepared("statement_#{i}", [r.to_s, '2017-01-01 07:29:33.096192', '2017-01-01 07:29:33.096192' ])
    i += 1
end

我已经更新了我的答案,以解决这个问题和其他问题。 - tadman
你应该在循环之前只准备一次查询。 - julp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接