似乎
limit()
没有添加到生成的子查询中,它实际上是一个Model::ActiveRecord_Relation
,而是尝试执行抛出错误的“
ActiveRecord::StatementInvalid 异常表不存在并返回nil
class Doc < ApplicationRecord
has_many :doc_dirs
has_many :dirs, through: :doc_dirs
default_scope -> { where(inactive: false, is_version_1: true)}
scope :doc_collection, -> do
str_sql = "( SELECT * FROM [D_docs] ) [D_docs]"
doc_collec = Doc.from(str_sql).limit(10)
# byebug
doc_collec
end
end
在 Rails 控制台上,如果您在结果
doc_collec = from(sql)
和 doc_collec
之间添加调试
运行
doc_collec = from(sql).to_sql
你会得到:
ActiveRecord::StatementInvalid 异常:表 '( SELECT * FROM [D_docs] ) [D_docs]' 不存在
应该注意的是
Doc.from(str_sql).to_sql
给出: SELECT [D_docs].* FROM ( SELECT * FROM [D_docs] ) [D_docs]
一个正确且没有错误的查询和较旧的 Rails 版本 (6.1.7) 和 SQL Server 适配器版本 6.x.x 成功生成了我们想要获取的查询
SELECT [D_docs].* FROM ( SELECT * FROM [D_docs] ) [D_docs] OFFSET 0 FETCH NEXT 10 ROWS ONLY
也
Doc.from(str_sql).order(:pkid)
按预期工作
详情
7.1.2
7.1.0
2.1.x
doc_collec.to_sql 应该是:
SELECT [D_docs].* FROM ( SELECT * FROM [D_docs] ) [D_docs] OFFSET 0 FETCH NEXT 10 ROWS ONLY
您的问题不清楚:
[D_docs]
是什么,因为看起来该表不存在?[D_docs]
来使用它?根据您的帖子,我做出以下假设(因为这是如上所述生成 SQL 代码的唯一方法)
class Doc < ApplicationRecord
self.table_name = "D_docs"
end
话虽这么说,我们可以构建您想要的功能,如下所示:
scope :doc_collection, -> do
Doc.from(
Arel::Nodes::TableAlias.new(
Doc.all.arel,
self.table_name)
).limit(10)
end
这将导致:
SELECT
[D_docs].*
FROM
(SELECT
[D_docs].*
FROM
[D_docs]
) [D_docs]
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY
如果
D_Docs
不是实际的表名,那么任何运行的 SQL 都会很奇怪,但是我们可以按如下方式修改上面的内容:
scope :doc_collection, -> do
d_doc = Arel::Table.new('D_docs')
Doc.from(
Arel::Nodes::TableAlias.new(
d_doc.project(d_doc[Arel.star]),
self.table_name)
).limit(10)
end
这会导致
SELECT
[docs].*
FROM
(SELECT
[D_docs].*
FROM
[D_docs]
) [docs]
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY