diff --git a/jOOQ-website/src/main/resources/manual-2.5.xml b/jOOQ-website/src/main/resources/manual-2.5.xml index 82cd61f270..92d1016084 100644 --- a/jOOQ-website/src/main/resources/manual-2.5.xml +++ b/jOOQ-website/src/main/resources/manual-2.5.xml @@ -278,6 +278,21 @@ SelectConnectByConditionStep connectBy(Condition condition);]]> */ @Support SelectSelectStep select(Field... fields);]]> + +

jOOQ and the Oracle SQL dialect

+

+ Oracle SQL is much more expressive than many other SQL dialects. It features many unique keywords, clauses and functions that are out of scope for the SQL standard. Some examples for this are +

+ + +

+ jOOQ has a historic affinity to Oracle's SQL extensions. If something is supported in Oracle SQL, it has a high probability of making it into the jOOQ API +

@@ -408,7 +423,7 @@ create.select()

jOOQ as an internal domain specific language in Java

- Many other frameworks have similar APIs with similar feature sets. Yet, what makes jOOQ special is its informal modeling a unified SQL dialect suitable for many vendor-specific dialects, and implementing that BNF notation as a hierarchy of interfaces in Java. This concept is extremely powerful, when with syntax completion. Not only can you code much faster, your SQL code will be compile-checked to a certain extent. An example of a DSL query equivalent to the previous one is given here: + Many other frameworks have similar APIs with similar feature sets. Yet, what makes jOOQ special is its informal modelling a unified SQL dialect suitable for many vendor-specific dialects, and implementing that BNF notation as a hierarchy of interfaces in Java. This concept is extremely powerful, when with syntax completion. Not only can you code much faster, your SQL code will be compile-checked to a certain extent. An example of a DSL query equivalent to the previous one is given here:

result = create.select() @@ -686,38 +701,438 @@ create.select() .join(BOOK_TO_BOOK_STORE) .on(BOOK_TO_BOOK_STORE.BOOK_ID.equal(BOOK.ID))) .on(BOOK.AUTHOR_ID.equal(AUTHOR.ID)));]]> + + + +

JOIN ON KEY, convenience provided by jOOQ

+

+ Surprisingly, SQL does not allow to formally JOIN on well-known foreign key relationship information. Naturally, when you join BOOK to AUTHOR, you will want to do that based on the BOOK.AUTHOR_ID foreign key to AUTHOR.ID primary key relation. Not being able to do this in SQL leads to a lot of repetitive code, re-writing the same JOIN predicate again and again - especially, when your foreign keys contain more than one column. With jOOQ, when you use , you can use foreign key constraint information in JOIN expressions as such: +

+ + + + + +

+ In case of ambiguity, you can also supply field references for your foreign keys, or the generated foreign key reference to the onKey() method. +

+ +

The JOIN USING syntax

+

+ Most often, you will provide jOOQ with JOIN conditions in the JOIN .. ON clause. SQL supports a different means of specifying how two tables are to be joined. This is the JOIN .. USING clause. Instead of a condition, you supply a set of fields whose names are common to both tables to the left and right of a JOIN operation. This can be useful when your database schema has a high degree of relational normalisation. An example: +

+ + + + + +

+ In schemas with high degrees of normalisation, you may also choose to use NATURAL JOIN, which takes no JOIN arguments as it joins using all fields that are common to the table expressions to the left and to the right of the JOIN operator. An example: +

+ + + + +

Oracle's partitioned OUTER JOIN

+

+ Oracle SQL ships with a special syntax available for OUTER JOIN clauses. According to the Oracle documentation about partitioned outer joins this can be used to fill gaps for simplified analytical calculations. jOOQ only supports putting the PARTITION BY clause to the right of the OUTER JOIN clause. The following example will create at least one record per AUTHOR and per existing value in BOOK.PUBLISHED_IN, regardless if an AUTHOR has actually published a book in that year. +

+ + + + +
The WHERE clause - + +

Apply filtering predicates in the WHERE clause

+

+ The WHERE clause can be used for JOIN or filter predicates, in order to restrict the data returned by the supplied to the previously specified and . Here is an example: +

+ + + + + +

+ The above syntax is convenience provided by jOOQ, allowing you to connect the supplied in the WHERE clause with another condition using an AND operator. You can of course also create a more complex condition and supply that to the WHERE clause directly (observe the different placing of parentheses). The results will be the same: +

+ + + + + +

+ You will find more information about creating later in the manual. +

+
The CONNECT BY clause - + +

Oracle's syntax for creating hierarchical queries

+

+ The Oracle database knows a very succinct syntax for creating hierarchical queries: the CONNECT BY clause, which is fully supported by jOOQ, including all related functions and pseudo-columns. A more or less formal definition of this clause is given here: +

+-- SELECT .. +-- FROM .. +-- WHERE .. + CONNECT BY [NOCYCLE] condition [AND condition, ...] [START WITH condition] +-- GROUP BY .. + +

+ An example for an iterative query, iterating through values between 1 and 5 is this: +

+ + + + + +

+ Here's a more complex example where you can recursively fetch directories in your database, and concatenate them to a path: +

+ + + + + +

+ The output might then look like this +

+ ++------------------------------------------------+ +|substring | ++------------------------------------------------+ +|C: | +|C:/eclipse | +|C:/eclipse/configuration | +|C:/eclipse/dropins | +|C:/eclipse/eclipse.exe | ++------------------------------------------------+ +|...21 record(s) truncated... + + +

+ Some of the supported functions and pseudo-columns are these (available from the ): +

+ + + +

+ Note that this syntax is also supported in the CUBRID database. +

+
The GROUP BY clause - + +

The GROUP BY clause used for grouping and aggregations

+

+ GROUP BY can be used to create unique groups of data, to form aggregations, to remove duplicates and for other reasons. It will transform your previously defined , and return only one record per unique group as specified in this clause. For instance, you can group books by BOOK.AUTHOR_ID: +

+ + + + + +

+ As defined in the SQL standard, when grouping, you may no longer project any columns that are not a formal part of the GROUP BY clause, or . The above example counts all books per author +

+ +

MySQL's deviation from the SQL standard

+

+ MySQL has a peculiar way of not adhering to this standard behaviour. This is documented in the MySQL manual. In short, with MySQL, you can also project any other field that are not part of the GROUP BY clause. The projected values will just be arbitrary values from within the group. You cannot rely on any ordering. For example: +

+ + + + + +

+ This will return an arbitrary title per author. jOOQ supports this syntax, as jOOQ is not doing any checks internally, about the consistence of tables/fields/functions that you provide it. +

+ +

ROLLUP(), CUBE() and GROUPING SETS()

+

+ Some databases support the SQL standard grouping functions and some extensions thereof. See the manual's section about for more details. +

+
The HAVING clause - + +

Restrict results from the GROUP BY clause using HAVING

+

+ The HAVING clause is commonly used to further restrict data resulting from a previously issued . An example, selecting only those authors that have written at least two books: +

+ + += 2]]> + + +

+ According to the SQL standard, you may omit the GROUP BY clause and still issue a HAVING clause. This will implicitly GROUP BY (). jOOQ also supports this syntax. The following example selects one record, only if there are at least 4 books in the books table: +

+ + += 4]]> + + +
The ORDER BY clause - + +

The ORDER BY clause

+

+ Databases are allowed to return data in any arbitrary order, unless you explicitly declare that order in the ORDER BY clause. In jOOQ, this is straight-forward: +

+ + + + + +

+ Any jOOQ can be transformed into an by calling the asc() and desc() methods. +

+ +

Ordering by field index

+

+ The SQL standard allows for specifying integer literals (, not !) to reference column indexes from the projection (). This may be useful if you do not want to repeat a lengthy expression, by which you want to order - although most databases also allow for referencing in the ORDER BY clause. An example of this is given here: +

+ + + + + +

+ Note, how one() is used as a convenience short-cut for inline(1) +

+ +

Ordering and NULLS

+

+ A few databases support the SQL standard "null ordering" clause in sort specification lists, to define whether NULL values should come first or last in an ordered result. +

+ + + + + +

+ If your database doesn't support this syntax, jOOQ simulates it using a as follows +

+ + + + +

Ordering using CASE expressions

+

+ Using in SQL ORDER BY clauses is a common pattern, if you want to introduce some sort indirection / sort mapping into your queries. As with SQL, you can add any type of into your ORDER BY clause. For instance, if you have two favourite books that you always want to appear on top, you could write: +

+ + + + + +

+ But writing these things can become quite verbose. jOOQ supports a convenient syntax for specifying sort mappings. The same query can be written in jOOQ as such: +

+ + + +

+ Of course, you can combine this feature with the previously discussed NULLS FIRST / NULLS LAST feature. So, if in fact these two books are the ones you like least, you can put all NULLS FIRST (all the other books): +

+ + + +

jOOQ's understanding of SELECT .. ORDER BY

+

+ The SQL standard defines that a "query expression" can be ordered, and that query expressions can contain , whose subqueries cannot be ordered. While this is defined as such in the SQL standard, many databases allowing for the non-standard in one way or another, do not adhere to this part of the SQL standard. Hence, jOOQ allows for ordering all SELECT statements, regardless whether they are constructed as a part of a UNION or not. Corner-cases are handled internally by jOOQ, by introducing synthetic subselects to adhere to the correct syntax, where this is needed. +

+
- The LIMIT clause - + The LIMIT .. OFFSET clause + +

The non-standard LIMIT .. OFFSET clause

+

+ While being extremely useful for every application that does paging, or just to limit result sets to reasonable sizes, this clause is not yet part of any SQL standard (up until SQL:2008). Hence, there exist a variety of possible implementations in various SQL dialects, concerning this limit clause. jOOQ chose to implement the LIMIT .. OFFSET clause as understood and supported by MySQL, H2, HSQLDB, Postgres, and SQLite. Here is an example of how to apply limits with jOOQ: +

+ + + +

+ This will limit the result to 1 books starting with the 2nd book (starting at offset 0!). limit() is supported in all dialects, offset() in all but Sybase ASE, which has no reasonable means to simulate it. This is how jOOQ simulates the above query in various SQL dialects: +

+ + 1 +AND ROWNUM_98843777 <= 3 +]]> + +

+ As you can see, jOOQ will take care of the incredibly painful ROW_NUMBER() OVER() (or ROWNUM for Oracle) filtering in subselects for you, you'll just have to write limit(1).offset(2) in any dialect. +

+ +

SQL Server's ORDER BY, TOP and subqueries

+

+ As can be seen in the above example, writing correct SQL can be quite tricky, depending on the SQL dialect. For instance, with SQL Server, you cannot have an ORDER BY clause in a subquery, unless you also have a TOP clause. This is illustrated by the fact that jOOQ renders a TOP 100 PERCENT clause for you. The same applies to the fact that ROW_NUMBER() OVER() needs an ORDER BY windowing clause, even if you don't provide one to the jOOQ query. By default, jOOQ adds ordering by the first column of your projection. +

+
@@ -726,7 +1141,7 @@ create.select()
- UNIONs, intersections, etc. + UNION, INTERSECTION and EXCEPT
@@ -861,12 +1276,20 @@ create.select() +
+ Grouping functions + +

Creating GROUPING SETS for reporting

+

The SQL standard defines

+
+
+
User-defined functions
-
+
The CASE expression
@@ -1085,6 +1508,23 @@ create.select()
+
+ Stored procedures and functions + + + +
+ Oracle Packages + +
+ +
+ Oracle user-defined types and member procedures + +
+
+
+
Formatting