Joh*_*hir 7 postgresql activerecord ruby-on-rails prepared-statement
我想做一个upsert.Rails还不支持这个.查询是这样的:
INSERT INTO foos (thing_id, bar_id) VALUES (1, 2)
ON CONFLICT (thing_id, bar_id) DO NOTHING
Run Code Online (Sandbox Code Playgroud)
我可以用self.class.connection.execute
或轻松做到这一点exec_insert
.但我也希望利用准备好的陈述.我以为我可以这样做:
thing_id = ActiveRecord::Relation::QueryAttribute.new("thing_id", thing.id, ActiveRecord::Type::Integer.new)
bar_id = ActiveRecord::Relation::QueryAttribute.new("bar_id", id, ActiveRecord::Type::Integer.new)
self.class.connection.exec_insert(<<-SQL, nil, [thing_id, bar_id])
INSERT INTO foos (thing_id, bar_id) VALUES ($1, $2)
ON CONFLICT (thing_id, bar_id) DO NOTHING
SQL
Run Code Online (Sandbox Code Playgroud)
但是当我试验这个时,似乎没有创建一个准备好的语句.
我试过这种风格:
query = <<-SQL
INSERT INTO foos (thing_id, bar_id) VALUES ($1, $2)
ON CONFLICT (thing_id, bar_id) DO NOTHING
SQL
connection = ActiveRecord::Base.connection.raw_connection
connection.prepare('some_name', query)
st = connection.exec_prepared('some_name', [ thing.id, id ])
Run Code Online (Sandbox Code Playgroud)
它确实创建了一个准备好的声明.但是,第二次运行时,postgres抱怨创建一个具有相同名称的预准备语句.因此,rails准备好的声明管理发生在这个级别以上,我无法在此处利用它.我必须在这里手动管理它.我不相信我能做到这一点,即使我能做到这一点也会很冗长.
execute
和朋友不接受接受的("foo=?", 1)
api where
.
有没有办法利用rails的自动化准备语句管理原始SQL?
#exec_query
接受一个可选的关键字参数,prepare
默认为 false。看看方法定义(和这里)。
鉴于下表定义:
CREATE TABLE foos (
thing_id INT,
bar_id INT,
UNIQUE (thing_id, bar_id)
);
Run Code Online (Sandbox Code Playgroud)
我测试了以下内容:
CREATE TABLE foos (
thing_id INT,
bar_id INT,
UNIQUE (thing_id, bar_id)
);
Run Code Online (Sandbox Code Playgroud)
这两种绑定参数样式都适用于 ActiveRecord 5.2.0 和 pg 1.0.0。使用相同值的多个 INSERT 语句最终只会插入一行而不会引发错误。我检查了 Postgres 日志,只有一个“解析”(在第一个 INSERT 之前),所以看起来准备好的语句机制被正确使用。
归档时间: |
|
查看次数: |
683 次 |
最近记录: |