21. 10. 2014

Limit v SQL dotazu na Oraclu a chyba ORA-00933

Máme následující SQL dotaz:

SELECT * FROM user WHERE username LIKE 'a%' LIMIT 10;
view raw Příklad 1.sql hosted with ❤ by GitHub
V PostgreSQL i MySQL projde správně a vrátí nám prvních deset uživatelů, jejichž uživatelské jméno začíná na "a". Na Oraclu ale skončí chybou:

ERROR at line 1:
ORA-00933: SQL command not properly ended
view raw Priklad2 hosted with ❤ by GitHub
Je to proto, že Oracle nezná klauzuli LIMIT. V určitých případech je možné místo ní použít pseudosloupeček ROWNUM:
For each row returned by a query, the ROWNUM pseudocolumn returns a number indicating the order in which Oracle selects the row from a table or set of joined rows. The first row selected has a ROWNUM of 1, the second has 2, and so on.
Například:

SELECT * FROM user WHERE first_name LIKE 'a%' and ROWNUM <= 10;
view raw 2.sql hosted with ❤ by GitHub
Je ale potřeba si dát pozor, že ne vždy funguje ROWNUM stejně jako LIMIT. Obzvlášť ve spojení s ORDER BY:

SELECT * FROM user WHERE first_name LIKE 'a%' and ROWNUM <= 10 ORDER BY age;
view raw 3.sql hosted with ❤ by GitHub
Tenhle dotaz nám může vrátit jiná data, než jaká bychom očekávali. Napřed se totiž vyhodnotí podmínka na ROWNUM a až pak se provede ORDER BY. To je rozdíl oproti původnímu dotazu, kde se napřed nalezené záznamy seřadí a až pak se aplikuje LIMIT.

Správný postup je původní dotaz vnořit do nového, který přidá podmínku s ROWNUM:

SELECT * FROM
(SELECT * FROM user WHERE username LIKE 'a%' ORDER BY age)
WHERE ROWNUM <= 10;
view raw 4.sql hosted with ❤ by GitHub
Více informací:

http://docs.oracle.com/cd/B19306_01/server.102/b14200/pseudocolumns009.htm
http://www.oracle.com/technetwork/issue-archive/2006/06-sep/o56asktom-086197.html

Žádné komentáře:

Okomentovat