Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ SQL » SqlArray Limit and Offset
SqlArray Limit and Offset [message #4466] Fri, 11 August 2006 01:03 Go to next message
zsolt is currently offline  zsolt
Messages: 697
Registered: December 2005
Location: Budapest, Hungary
Contributor
I have implemented it. I don't know if this is a good interface or not, but I hope so.

SqlArray declaration private section (SqlCtrl.h):
	unsigned int limit;
	bool        limit_set;
	int64       offset;
	bool        offset_set;


SqlArray declaration public section:
	SqlArray& SetLimit(unsigned int _limit)                { limit = _limit; limit_set = true; return *this; }
	SqlArray& SetOffset(int64 _offset)                     { offset = _offset; offset_set = true; return *this; }


In SqlArray::SqlArray() and SqlArray::Clear()
	limit_set = false;
	offset_set = false;


In void SqlArray::AppendQuery(SqlBool where)
I have changed
		sql * ::Select(cols).From(table).Where(wh).OrderBy(orderby);

to
		SqlSet set = ::Select(cols).From(table).Where(wh).OrderBy(orderby);
		if(limit_set)
			if(offset_set) set.Limit(offset, limit);
			else set.Limit(limit);
		else
			if(offset_set) set.Offset(offset);
		sql * set;
Re: SqlArray Limit and Offset [message #4467 is a reply to message #4466] Fri, 11 August 2006 08:35 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
zsolt wrote on Thu, 10 August 2006 19:03

I have implemented it. I don't know if this is a good interface or not, but I hope so.



I do not like it too much, but I am unable to invent anything better Wink

Well, in fact, what I would like to have is to make this compatible with Oracle somehow. Well, I believe, with "Limit" it is simple - ignoring in oracle is all we need.

Mirek
Re: SqlArray Limit and Offset [message #4468 is a reply to message #4467] Fri, 11 August 2006 09:05 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
http://www.petefreitag.com/item/451.cfm

What about joining Limit and Offset into single command (in SqlExp)? You are unlikely to use Offset without the Limit...

E.g. Rows(offset, number) and Rows(number) overloads?

Select(FOO).From(BAR).Rows(100, 10);

Mirek
Re: SqlArray Limit and Offset [message #4469 is a reply to message #4468] Fri, 11 August 2006 09:41 Go to previous messageGo to next message
zsolt is currently offline  zsolt
Messages: 697
Registered: December 2005
Location: Budapest, Hungary
Contributor
Quote:

Well, in fact, what I would like to have is to make this compatible with Oracle somehow. Well, I believe, with "Limit" it is simple - ignoring in oracle is all we need.

I don't think, ignorance is a good idea. It should be implemented on client side somehow. Maybe that Rows() method should not use the internal text variable, only some internal limit and offset variables. Sql class should put together a statement or implement limit/offset on client side based on SqlExp's internal limit/offset variables and Database capabilities.
Re: SqlArray Limit and Offset [message #4470 is a reply to message #4468] Fri, 11 August 2006 09:50 Go to previous messageGo to next message
zsolt is currently offline  zsolt
Messages: 697
Registered: December 2005
Location: Budapest, Hungary
Contributor
An other idea:
I think Limit(offset, limit) and Limit(limit) methods would be better than Rows() methods, because Limit() shows more cleanly what it's purpose is.
Re: SqlArray Limit and Offset [message #4471 is a reply to message #4470] Fri, 11 August 2006 18:36 Go to previous messageGo to next message
rbmatt is currently offline  rbmatt
Messages: 90
Registered: July 2006
Location: Tennesse, USA
Member

zsolt wrote on Fri, 11 August 2006 03:50

An other idea:
I think Limit(offset, limit) and Limit(limit) methods would be better than Rows() methods, because Limit() shows more cleanly what it's purpose is.

I agree that this nomenclature is better. I know what it means to limit an sql query, but I would have no clue what Rows() would do.
Re: SqlArray Limit and Offset [message #4472 is a reply to message #4471] Fri, 11 August 2006 18:44 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
OK!

Mirek
Re: SqlArray Limit and Offset [message #4489 is a reply to message #4472] Fri, 11 August 2006 23:47 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Added (not quite tested Smile

I will defer dialect-independent Limit to new SqlExp.

Mirek
Re: SqlArray Limit and Offset [message #4789 is a reply to message #4489] Tue, 22 August 2006 14:10 Go to previous messageGo to next message
zsolt is currently offline  zsolt
Messages: 697
Registered: December 2005
Location: Budapest, Hungary
Contributor
Some fixes:

1. changed SqlArray::Limit(int offset, int count); in SqlCtrl.h to
	void      Limit(int _offset, int _count)               { offset = _offset; count = _count; }

The definition was missing.

2. changed a line in void SqlArray::AppendQuery(SqlBool where) method from
sql * ::Select(cols).From(table).Where(wh).Limit(count).Offset(offset).OrderBy(orderby);

to
sql * ::Select(cols).From(table).Where(wh).OrderBy(orderby).Limit(count).Offset(offset);

LIMIT and OFFSET have to be at the end of the SQL statement.
Re: SqlArray Limit and Offset [message #4791 is a reply to message #4789] Tue, 22 August 2006 15:21 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Applies (hopefully correctly this time Wink

Mirek
Re: SqlArray Limit and Offset [message #7293 is a reply to message #4791] Wed, 20 December 2006 16:49 Go to previous messageGo to next message
fabio is currently offline  fabio
Messages: 9
Registered: November 2006
Promising Member
In oracle limit and offset not work......

Is very hard implement oracle dialect version of .Limit() and .Offset() why original query be bound to encapsulated in another select.
.......
SELECT * FROM (original query....) WHERE ROWNUM BETWEEN my_offset AND my_offset+my_limit;
.......

In SqlArray is possible to test Dialect and make another query (2 nested select) only for oracle dialect.

Any other idea ?

Fabio





Re: SqlArray Limit and Offset [message #7297 is a reply to message #7293] Wed, 20 December 2006 21:00 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
fabio wrote on Wed, 20 December 2006 10:49

In oracle limit and offset not work......

Is very hard implement oracle dialect version of .Limit() and .Offset() why original query be bound to encapsulated in another select.
.......
SELECT * FROM (original query....) WHERE ROWNUM BETWEEN my_offset AND my_offset+my_limit;
.......

In SqlArray is possible to test Dialect and make another query (2 nested select) only for oracle dialect.

Any other idea ?



Actually, dialects are gone. U++ is now able to "compile" SqlExp for each rdbms (well, able in sense that core of technology is there, but not all variants are implemented).

Anyway, in this case, it is indeed a problem because Oracle lacks this clause.

Mirek
Re: SqlArray Limit and Offset [message #7309 is a reply to message #7297] Thu, 21 December 2006 15:17 Go to previous messageGo to next message
fabio is currently offline  fabio
Messages: 9
Registered: November 2006
Promising Member
The 2 level query work only for first time....

the solution is (from http://www.oracle.com/technology/oramag/oracle/06-sep/o56ask tom.html)

... 3 level select.....
select * from ( select a.*, ROWNUM as row_num from ( 
select .......... from .... where ...... order by ......
) a where rownum <= offset+limit) where row_num > offset


Upp working solution is ...

1) Change in file: upp\uppsrc\sql\SqlCtrl\SqlArray.cpp

SqlArray::AppendQuery() method:
sql * ::Select(cols).From(table).Where(wh).OrderBy(orderby).Limit(count).Offset(offset);

in:

sql * ::Select(cols).From(table).Where(wh).OrderBy(orderby).Limit(offset,count);


2) Change in file: upp\uppsrc\sql\Sql\SqlStatement.cpp

SqlSelect& SqlSelect::Limit(int64 offset, int limit) {

    text = SqlCase(ORACLE,"select * from ( select rownum_a.*, ROWNUM as row_num from ( ")() + text +
           SqlCase(ORACLE,Format(") rownum_a where rownum <= %d ) where row_num > %d", offset+limit,offset))
                  (Format(" limit %d, %d",offset,limit));

	return *this;
}


this query use rownum reserved word, row_num, rownum_a user word and generate an extra column row_num in the result.


3) optional ?
Remove SqlSelect::Limit(count)
Remove SqlSelect::Offset(offset)
for complete portability

Tested in oracle and sqlite, my be work in MySql (same syntax of sqlite).

Fabio
  • Attachment: limit.zip
    (Size: 3.91KB, Downloaded 326 times)
Re: SqlArray Limit and Offset [message #7318 is a reply to message #7309] Thu, 21 December 2006 21:49 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Should not we rather store limit/offset and use it when final query is generated?

Mirek
Re: SqlArray Limit and Offset [message #7347 is a reply to message #7318] Sat, 23 December 2006 10:01 Go to previous messageGo to next message
fabio is currently offline  fabio
Messages: 9
Registered: November 2006
Promising Member
I am sorry for delay.....

Limit(offset,limit) is for actual (complete) query, and work only if used at end of query.

Why store for future use?

I think not possble implement multi-level "limit" in oracle.
This Oracle eccentric method require 2 extra query with extra column (rownum as row_num1...) with unique name. It is a hard work.

I can store not directly in "text" of SqlSelect class, but in new two string like "pre_text" and "post_text" (as in my first only-thinked version of Limit() method), but it also require an adjustment of SqlSelect class.

..... i am lazy .....

Fabio
Re: SqlArray Limit and Offset [message #7358 is a reply to message #7347] Sat, 23 December 2006 12:55 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
fabio wrote on Sat, 23 December 2006 04:01

I am sorry for delay.....

Limit(offset,limit) is for actual (complete) query, and work only if used at end of query.

Why store for future use?

I think not possble implement multi-level "limit" in oracle.
This Oracle eccentric method require 2 extra query with extra column (rownum as row_num1...) with unique name. It is a hard work.

I can store not directly in "text" of SqlSelect class, but in new two string like "pre_text" and "post_text" (as in my first only-thinked version of Limit() method), but it also require an adjustment of SqlSelect class.

..... i am lazy .....



Well, thinking about it even more...

Maybe we just stop at the fact that Oracle lacks support for these.

In fact, Oracle/U++ is may daily bread and I never really needed offset/limit. Somehow that is not how Oracle is used.

Mirek
Re: SqlArray Limit and Offset [message #7408 is a reply to message #7358] Wed, 27 December 2006 17:09 Go to previous messageGo to next message
fabio is currently offline  fabio
Messages: 9
Registered: November 2006
Promising Member
You can implement "limit and offset" at fetch level.
Many objects (Java, VB...) fetch and discard rows, simulating (one-way) limit and offset.....

In oracle 10g (and 9) is present a new version of OCIStmtFetch for make a clean limit solution:

 OCIStmtFetch2(stmthp, errhp, 1, OCI_FETCH_RELATIVE, fetchOffset, OCI_DEFAULT);

This fetches a row from the (scrollable) result set.


But, this oci function, and scrollable cursor feacture, is not present in oci8.

Fabio
Re: SqlArray Limit and Offset [message #7484 is a reply to message #7408] Sun, 31 December 2006 09:27 Go to previous message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Well, I am still a bit puzzled about what is limit/offset useful for... Smile (Must be all these years with Oracle 7)

Mirek
Previous Topic: SqlArray::SetDistinct()
Next Topic: ODBC ?
Goto Forum:
  


Current Time: Mon Apr 29 03:26:35 CEST 2024

Total time taken to generate the page: 0.04652 seconds