Hibernate setMaxResults() not working for Sybase database query - sql

Either of the following two approaches to executing a simple Hibernate query with limited results do not work in Sybase. They both result in a SybSQLException: Incorrect syntax near '#p0'.
Query q = session.createQuery( "from Record" );
q.setMaxResults( 50 );
q.list();
or
Criteria criteria = session.createCriteria( Record.class );
criteria.setMaxResults( 50 );
criteria.list();
It appears the actual SQL generated in both of these cases looks like...
select top ? record_id, etc...
and Sybase is balking at the ?, which Hibernate is not filling in with the value 50 (this is my guess). I've searched everywhere and while others have encountered a similar error, it was not due to attempting to limit the results.
I can execute a direct SQL statement such as 'select top 50 from Record' and it works perfectly, so I know my version of Sybase supports the syntax.
I'm using Hibernate 3.2 and Sybase ASE 15.0.2

Perhaps you configured Hibernate to use a wrong SQL dialect.
It looks like HSQLDialect is the only dialect that can produce limit ? ?, and it's definitely a wrong choice for Sybase.
See also:
3.4.1. SQL Dialects

Try putting setFirstResult(1) as well like:
Criteria criteria = session.createCriteria(Record.class);
criteria.setFirstResult(1);
criteria.setMaxResults(50);
criteria.list();
Do you still get the same error?

setMaxResults() is typically used together with setFirstResult() to implement paging. Eg. the first query returns records 1 to 1000, the second query returns 1001 to 2000, and so on. Try using together.
setFetchSize() control how many rows are fetched at a time by the JDBC driver.(if implemented) So, if you for example have setMaxResults(1000) and setFetchSize(100) the query will return no more than 1000 rows, and will do so in batches of 100 rows at a time.

You can use createSQLQuery option which works with TOP.

Related

SQL error while using limit keyword in Derby

I have used limit keyword as:
"select * from empl3 limit "+4
But I am getting the error as:
Syntax error: Encountered "4" at line 1, column 27.
I am using Derby database.
As documented in the manual there is no LIMIT clause in Derby.
Derby uses the SQL standard for limiting the number of rows:
select *
from empl3
fetch first 4 rows only;
I believe the +4 after the select statement is giving you the error. You should return all of your data necessary for you page select * from empl3, but handle the paging in your page itself.
The key is in your words I am using derby database - see Does Derby support a LIMIT command.
You can either use the workaround suggested in the linked FAQ, or implement paging on your own, as suggested by WEI_DBA.

What's the generated query in sql for setFirstResult function in hibernate

What’s the generated query in sql server for this query in hibernate:
Criteria c = session.createCriteria(...);
c.setFirstResult(10);
c.setMaxResults(20);
Try executing it and watching your console for the query that's being created.
Since you're using multiple criteria, you'll need to experiment to see the exact effect that setFirstResult is having.

Documentum Query Language Syntax

I would like to know if there is a way in DQL to fetch the rows based on the start and end row values. (Like row number 1 - 1000, 1001 - 2000). ( Similar to what rownumber in oracle queries).
This input will be of great help.
For Documentum DQL query Pagination you can (should) use RETURN RANGE hint, like this
select * from dm_document where object_name like 'ABC%' enable(RETURN_RANGE 1001 2000 1000 'object_name ASC' )
it will sort documents by object_name and then return up to 1K rows, starting from the row number 1001 ending to 2000, optimized for 1K top (sorted) rows.
Syntax is RETURN_RANGE starting_row ending_row [optimize_top_row] 'sorting_clause'
It works since Content Server CS 6.6 with any underlying database.
Documentum Community Ref
I do not believe this is possible using DQL. However, you can consult the DQL Reference Guide (check Powerlink), which contains information about DQL hints (there is a section on them). There is a discussion of passthrough hints that allow you to pass hints through to the underlying RDBMS. The hints available depend on whether it is Oracle, SQL Server, DB2, etc.
This is an excerpt from that section:
Passthrough hints are hints that are passed to the RDBMS server. They
are not handled by Content Server.
SQL Server and Sybase have two
kinds of hints: those that apply to individual tables and those that
apply globally, to the entire statement. To accommodate this, you can
include passthrough hints in either a SELECT statement’s source list
or at the end of the statement. The hints you include in the source
list must be table‑specific hints. The hints you include at the end of
the statement must be global hints. For example, the following
statement includes passthrough hints for Sybase at the table level and
the statement level:
SELECT "r_object_id" FROM "dm_document" WITH
(SYBASE('NOHOLDLOCK')) WHERE "object_name"='test' ENABLE (FORCE_PLAN)
For DB2 and Oracle, include passthrough hints only at the end of the
SELECT statement.

SQL Query in Hibernate

I'm carrying out a SQL query which looks like:
SELECT thi.*
FROM track_history_items thi
JOIN artists art
ON thi.artist_id = art.id
WHERE thi.type = TrackBroadcast
Group By art.name
ORDER thi.created_at DESC
This works fine when I run it directly on my database from MySql Workbench, but when I run in through Hibernate, I get a No Dialect mapping for JDBC type: -1 error.
Anyone have any ideas what could be causing it?
Probably one or more of the columns in the query is not supported by the mysql dialect... try expanding the * and add one column at a time until you find the offending one.
Then it is just a matter of deciding whether you need that column or not.

Access DB update one table with value from another

I'm trying to update all records in one table with the values found in another table.
I've tried many versions of the same basic query and always get the same error message:
Operation must use an updateable
query.
Any thoughts on why this query won't work in Access DB?
UPDATE inventoryDetails as idet
SET idet.itemDesc =
(
SELECT bomItemDesc
FROM BOM_TEMPLATES as bt
WHERE bt.bomModelNumber = idet.modelNumber
)
also tried this because I realized that since the second table has multiple model number records for each modelnumber - and I only need the first description from the first record found for each model number.
UPDATE inventoryDetails as idet
SET idet.item_desc =
(
SELECT TOP 1 bomItemDescription
FROM BOM_TEMPLATES as bt
WHERE bt.bomModelNumber = idet.modelNumber
)
...still getting the same error though.
You have to use a join
UPDATE inventoryDetails
INNER JOIN BOM_TEMPLATES ON inventoryDetails.modelNumber = BOM_TEMPLATES.bomModelNumber
SET inventoryDetails.itemDesc = [bomItemDesc];
Any thoughts on why this query won't work in Access DB?
The answer is, because ACE/Jet SQL syntax is not SQL-92 compliant (even when in its ANSI-92 Query Mode!).
I'm assuming yours is a scalar subquery. This construct is simply not supported by ACE/Jet.
ACE/Jet has its own quirky and flawed UPDATE..JOIN syntax, flawed because the engine doesn't force the JOINed values to be scalar and it is free to silently use an arbitrary value. It is different again from SQL Server's own UPDATE..JOIN syntax but at least SQL Server supports the Standard scalar subquery as an alternative. ACE/Jet forces you to either learn its quirky non-portable ways or to use an alternative SQL product.
Sorry to sound negative: the ACE/Jet engine is a great piece of software but UPDATE syntax is absolutely fundamental and the fact it hasn't been changed since the SQL-92 Standard really show its age.
try:
update idet
SET idet.itemDesc = bt.bomItemDesc
from inventoryDetails as idet
inner join BOM_TEMPLATES as bt
on bt.bomModelNumber = idet.modelNumber
This is how I would write it for SQL server. Hope Access understands the same command.