如何在 SubSonic 2.2 中执行 Oracle top-n(分页)查询?
(免责声明:出于安全原因,我在此处更改/混淆了一些变量/表/列名称。如果某些内容看起来有点不对劲,请原谅我。)
我正在构建一个Oracle 10g 数据库的前端,我正在尝试获取分页数据。除了分页之外,以下 SubSonic 2.2 代码按照我想要的顺序为我提供了我想要的内容:
var q = new Select()
.From(AppDb.MyTable.Schema)
.Where(AppDb.MyTable.DisabledDateColumn).IsNull()
.OrderDesc(AppDb.MyTable.CreatedDateColumn.ColumnName)
System.Console.Out.Writeline(q.BuildStatement());
这产生了以下 SQL:
SELECT
MYSCHEMA.MYTABLE.ID,
MYSCHEMA.MYTABLE.DISABLED_DATE
FROM
MYSCHEMA.MYTABLE
WHERE
MYSCHEMA.MYTABLE.DISABLED_DATE IS NULL
ORDER BY
CREATED_DATE DESC
然后我尝试引入分页:
var q = new Select()
.From(AppDb.MyTable.Schema)
.Where(AppDb.MyTable.DisabledDateColumn).IsNull()
.OrderDesc(AppDb.MyTable.CreatedDateColumn.ColumnName)
.Paged(0, 10);
它消除了我的 WHERE 和 ORDER BY 子句:
SELECT * FROM (
SELECT
MYSCHEMA.MYTABLE.ID,
MYSCHEMA.MYTABLE.DISABLED_DATE,
ROWNUM as row_number
FROM
MYSCHEMA.MYTABLE
)
WHERE
row_number BETWEEN 1 AND 10
我是品牌SubSonic 是新手,所以我不知道这是否是一个错误,或者我只是没有按照首选方式执行此操作,或者 Oracle 是否要求以不同的、更以 Oracle 为中心的方式完成此操作。 (Oracle 似乎要求所有内容都如此。)
我想要的是,如果不是很明显,我想要的是每个后续页面都包含 10 个下一个最近创建的非禁用记录。我怎样才能在 SubSonic 2.2 中做到这一点?
(Disclaimer: I changed/obfuscated some of the variable/table/column names here for security reasons. Please forgive me if something looks a little off.)
I am building a front-end to an Oracle 10g database, and I'm trying to get paged data. Aside from paging, the following SubSonic 2.2 code gives me what I want, in the order I want it:
var q = new Select()
.From(AppDb.MyTable.Schema)
.Where(AppDb.MyTable.DisabledDateColumn).IsNull()
.OrderDesc(AppDb.MyTable.CreatedDateColumn.ColumnName)
System.Console.Out.Writeline(q.BuildStatement());
This yields the following SQL:
SELECT
MYSCHEMA.MYTABLE.ID,
MYSCHEMA.MYTABLE.DISABLED_DATE
FROM
MYSCHEMA.MYTABLE
WHERE
MYSCHEMA.MYTABLE.DISABLED_DATE IS NULL
ORDER BY
CREATED_DATE DESC
Then I try to introduce paging:
var q = new Select()
.From(AppDb.MyTable.Schema)
.Where(AppDb.MyTable.DisabledDateColumn).IsNull()
.OrderDesc(AppDb.MyTable.CreatedDateColumn.ColumnName)
.Paged(0, 10);
And it wipes out my WHERE and ORDER BY clauses:
SELECT * FROM (
SELECT
MYSCHEMA.MYTABLE.ID,
MYSCHEMA.MYTABLE.DISABLED_DATE,
ROWNUM as row_number
FROM
MYSCHEMA.MYTABLE
)
WHERE
row_number BETWEEN 1 AND 10
I'm brand new to SubSonic, so I don't know if that's a bug, or I'm just not doing it the preferred way, or if Oracle demands that this be done in a different, more Oracle-centric way. (Oracle seems to demand that of everything.)
What I want, in case it isn't obvious, is each succeeding page to include the 10 next most-recently-created, non-disabled records. How can I do this in SubSonic 2.2?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
看起来您的查询没有生成与当前 Oracle Data Provider for SubSonic 应该。以下是相关代码(从第 852 行开始):
也许更新当前源代码就可以解决问题。如果实际提供程序出现问题,您可以将其与 SqlDataProvider 进行比较,以获取可能存在问题的提示。
It looks like your query is not generating the same SQL as the current Oracle Data Provider for SubSonic should. Here is the relevant code (starting at line 852):
Perhaps an update to current source would do the trick. If there is something wrong with the actual provider, you can compare it to the SqlDataProvider for hints as to what might be the problem.
我在使用 NET 2.0 和 Oracle 9i R2 的环境中,遇到了同样的问题。我正在使用 SubSonic 2.2。
我从 GitHub 下载了源代码,这就是我发现的:
@ranomore (OracleDataProvider.GetSelectSql()) 引用的代码仅在使用 SubSonic.Query 对象时才会被调用。由于 OP 和我自己使用从更新且更强大的 SubSonic.SqlQuery 对象派生的 Select 对象,因此 OracleDataProvider.GetSelectSql() 永远不会被调用。相反,OracleGenerator.BuildPagedSelectStatement()被调用并生成您在 OP 发布的 SQL。此代码存在错误,因为它从未将 WHERE 和 ORDER BY 子句添加到其最终生成的分页查询中。
我用基于 ANSISqlGenerator.BuildSelectStatement() 的内容替换了 BuildPagedSelectStatement() 的内容:
上面的内容对我有用。希望这对其他人有帮助!
I'm in an environment using NET 2.0 and Oracle 9i R2 and I ran into the same exact problem. I'm using SubSonic 2.2.
I downloaded the source from GitHub and this is what I found:
The code quoted by @ranomore (OracleDataProvider.GetSelectSql()) is only called when using the SubSonic.Query object. Since the OP and myself use the Select object which is derived from the newer and more powerful SubSonic.SqlQuery object, OracleDataProvider.GetSelectSql() never gets called. Instead, OracleGenerator.BuildPagedSelectStatement() gets called and generates the SQL you see posted by the OP. This code is buggy as it never adds the WHERE and ORDER BY clauses to the pagination query it ultimately generates.
I replaced the contents of BuildPagedSelectStatement() with something based on ANSISqlGenerator.BuildSelectStatement():
The above worked for me. Hope this helps others!
如果内部 SQL 由第一个语句(包括 where 和 order by)组成,Oracle 就可以使用 Top-N 查询。
所以,我想说 Oracle 没有特定的理由来忽略它们。
从未使用过亚音速,不知道是否需要在那里做不同的事情。
就性能而言,DISABLED_DATE、CREATED_DATE 上的索引应该可以解决问题(请参阅:http://blog.fatalmind.com/2010/07/30/analytic-top-n-queries/)。
Oracle would be fine with the Top-N query if the inner SQL would consist of the first statement (including where and order by).
So, i'd say there is no Oracle specific reason to omit them.
Never used subsonic, don't know if you need to do it different there.
Performance wise, an index on DISABLED_DATE, CREATED_DATE should do the trick (see: http://blog.fatalmind.com/2010/07/30/analytic-top-n-queries/).