gpt4 book ai didi

ruby-on-rails - 我可以执行原始 sql 查询,利用准备好的语句,而不使用 ActiveRecord::Relation::QueryAttribute 吗?

转载 作者:行者123 更新时间:2023-11-29 11:22:17 25 4
gpt4 key购买 nike

我想做一个 upsert . Rails 还不支持这个。查询是这样的:

INSERT INTO foos (thing_id, bar_id) VALUES (1, 2)
ON CONFLICT (thing_id, bar_id) DO NOTHING

我可以使用 self.class.connection.executeexec_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

但是当我对此进行试验时,似乎没有创建准备好的语句。

我试过这种风格:

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 ])

它确实创建了一个准备好的语句。但是,第二次运行时,postgres 提示创建了一个同名的准备好的语句。因此,rails 的准备好的语句管理发生在这个级别之上,我无法在这里利用它。我将不得不在这里手动管理它。我不确定我能否正确地做到这一点,即使我能这样做也会很冗长。

execute 和 friends 不接受 ("foo=?", 1) where 接受的 api。

有什么方法可以利用 Rails 对原始 SQL 的自动准备好的语句管理吗?

最佳答案

#exec_query 接受一个可选的关键字参数,prepare,默认为 false。看看 method definition (和 here )。

给定下表定义:

CREATE TABLE foos (
thing_id INT,
bar_id INT,
UNIQUE (thing_id, bar_id)
);

我测试了以下内容:

conn = ActiveRecord::Base.connection
stmt = 'INSERT INTO foos (thing_id, bar_id) VALUES ($1, $2) ' \
'ON CONFLICT (thing_id, bar_id) DO NOTHING'

# "Old" bind parameters
binds = [[nil, 1], [nil, 2]]
conn.exec_query stmt, 'SQL', binds, prepare: true
conn.exec_query stmt, 'SQL', binds, prepare: true

# "New" bind parameters
type = ActiveModel::Type::Integer.new limit: 4
binds = [
ActiveRecord::Relation::QueryAttribute.new('thing_id', 1, type),
ActiveRecord::Relation::QueryAttribute.new('bar_id', 2, type)
]
conn.exec_query stmt, 'SQL', binds, prepare: true
conn.exec_query stmt, 'SQL', binds, prepare: true

这两种绑定(bind)参数样式都适用于 ActiveRecord 5.2.0 和 pg 1.0.0。使用相同值的多个 INSERT 语句最终只会插入一行,而不会引发任何错误。我检查了 Postgres 日志,只有一个“解析”(在第一个 INSERT 之前),因此看来准备好的语句机制被正确使用。

关于ruby-on-rails - 我可以执行原始 sql 查询,利用准备好的语句,而不使用 ActiveRecord::Relation::QueryAttribute 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49947990/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com