我在VisualWorks中使用Glorp并使用Oracle数据库。因为Oracle不知道LIMIT命令,所以在查询后返回 all ,WHERE子句的计算结果为true的myTable记录。
q := Glorp.SimpleQuery
returningManyOf: MyTable
where: [:each | each name = 'test']
limit: 10.
q orderBy: [:each | each id descending].
results:= aGlorpSession execute: q.
如何在此Glorp查询中加入ROWNUM?
//编辑生成的SQL:
SELECT t1.id, t1.name
FROM MyTable t1
WHERE (t1.name= ?) ORDER BY t1.id DESC
答案 0 :(得分:1)
即使您可以将ROWNUM添加到此查询中,您仍可能无法获得所需的结果。问题是WHERE子句在ORDER BY之前应用 - 因此,通过限制返回的前10行,您将获得这10行,然后它们将被排序。这是一个例子:
CREATE TABLE order_test(seq_num NUMBER);
INSERT INTO order_test(seq_num) VALUES(20);
INSERT INTO order_test(seq_num) VALUES(19);
INSERT INTO order_test(seq_num) VALUES(18);
INSERT INTO order_test(seq_num) VALUES(17);
INSERT INTO order_test(seq_num) VALUES(16);
INSERT INTO order_test(seq_num) VALUES(15);
INSERT INTO order_test(seq_num) VALUES(14);
INSERT INTO order_test(seq_num) VALUES(13);
INSERT INTO order_test(seq_num) VALUES(12);
INSERT INTO order_test(seq_num) VALUES(11);
INSERT INTO order_test(seq_num) VALUES(10);
INSERT INTO order_test(seq_num) VALUES(09);
INSERT INTO order_test(seq_num) VALUES(08);
INSERT INTO order_test(seq_num) VALUES(07);
INSERT INTO order_test(seq_num) VALUES(06);
INSERT INTO order_test(seq_num) VALUES(05);
INSERT INTO order_test(seq_num) VALUES(04);
INSERT INTO order_test(seq_num) VALUES(03);
INSERT INTO order_test(seq_num) VALUES(02);
INSERT INTO order_test(seq_num) VALUES(01);
SELECT * FROM order_test WHERE ROWNUM < 10 ORDER BY seq_num;
查询返回
12
13
14
15
16
17
18
19
20
在我的系统上。我怀疑你想要的是等同于
SELECT *
FROM (SELECT * FROM ORDER_TEST ORDER BY SEQ_NUM)
WHERE ROWNUM < 10
返回1到9。
我不知道您是否或如何在Glorp中嵌套查询。 (FWIW - 我知道并喜欢Smalltalk,但我因为这样的原因而讨厌持久性框架)。 YMMV,显然。
(顺便说一句 - 考虑一下这一点,您可以修改Glorp.SimpleQuery上的#limit:方法,将ROWNUM的比较注入到WHERE子句中 - 但正如我上面所述,结果可能仍然没有这是一个实施,留给感兴趣的读者: - )。
分享并享受。
答案 1 :(得分:1)
首先,我建议使用不同的语法 Glorp.Query读取:... 你真的不想在前面指定SimpleQuery类,并且读取:比returnsManyOf短得多:并且完成同样的事情。
我目前没有在我面前的软件,但我很确定在Oracle上的限制:命令应转换为使用rownum。您看到这会生成什么SQL?
答案 2 :(得分:1)
On Smalltalk.Glorp.DatabasePlatform我添加了两个空方法#printPreLimitWrapper:on:和#printPostLimitWrapper:on:我在Smalltalk.Glorp.OraclePlatform中重写:
printPreLimitWrapper: anInteger on: aCommand
aCommand nextPutAll: ' SELECT * FROM ( '
printPostLimitWrapper: anInteger on: aCommand
aCommand nextPutAll: ' ) WHERE ROWNUM <= '.
anInteger printOn: aCommand.
aCommand nextPutAll: ' '.
On Smalltalk.Glorp.SimpleQuery我添加了:
printPostLimitWrapperOn: aCommand
self hasLimit ifFalse: [^self].
self platform printPostLimitWrapper: self limit on: aCommand.
printPreLimitWrapperOn: aCommand
self hasLimit ifFalse: [^self].
self platform printPreLimitWrapper: self limit on: aCommand.
在Smalltalk.Glorp.QuerySelectCommand上,我改变了以下方法:
printSQL
query printPreLimitWrapperOn: self.
stream nextPutAll: 'SELECT '.
query printSelectFieldsOn: self.
self findBoundExpressions.
query printTablesOn: self.
query printWhereClauseOn: self.
query printJoinsOn: self.
query printOrderingOn: self.
query printGroupByOn: self.
query printPostLimitOn: self.
query printOffsetOn: self.
query printPostLimitWrapperOn: self.