I am trying implement a paging and sorting repository with a #Query annotation. The query is simple enough:
SELECT DISTINCT(B.batch), B.scanDate, COUNT(B.batchReferenceNumber) as TransactionCount FROM Batch B
My database is SQL Server. The query that is getting generated is:
select
distinct batch0_.BatchNumber as col_0_0_,
count(batch0_.BatchNumber) as col_8_0_
from
BATCH batch0_
order by
batch0_.BatchNumber asc offset ? rows fetch next ? rows only
I get an error: Incorrect syntax near 'offset'.
The reason is "Offset" was not introduced until SQL Server 2012.
Is there any way around this? Or do I need to implement my own repository versus using the interface?
The SQL for the offset/limit clause is generated by your JPA provider.
You might be able to fix this by configuring the correct SqlDialect or if no such dialect is available you may raise an issue with that project.
Related
I have a view in SQL Server named item_movement, now I want to query using Microsoft Query in Excel:
select * from item_movement
But I'm getting this error - why? Is it possible to use Microsoft Query for querying views?
Found out the issue had to use the keyword
use mydbname before query
In our project we are using two databases, one postgres and one mssql. We are using Jooq in order to query these DBs and with postgres everything was pretty straight forward!
But with mssql we are facing some troubles. The task is to select the top 10 values and let's say that we have the following java code:
DSL.using(conn)
.select(USE_CASE.asterisk())
.from(USE_CASE)
.where(USE_CASE.RECORD_ACTIVE.eq(true))
.orderBy(USE_CASE.CREATED_ON.desc())
.limit(10)
.offset(0)
.fetch(new UseCaseMapper()))
This works like a charm with postgres but on mssql we get the following error:
Execution exception[[CompletionException: org.jooq.exception.DataAccessException:
SQL [select "park"."dbo"."use_case".* from "park"."dbo"."use_case" where
"park"."dbo"."use_case"."record_active" = ?
order by "park"."dbo"."use_case"."created_on" desc limit ?];
Incorrect syntax near 'limit'.]]
I know that for mssql the equivalent query would be something like,
select top 10 *
from use_case
where record_active = true
order by created_on desc;
How can I change my java code to get the limit records in mssql?
Correct SQLDialect
The exception message hints at the fact that you're still using the PostgreSQL (or some other non-SQL Server) dialect as your catalogs/schemas/tables/columns are quoted using "double_quotes", instead of [brackets].
Just use SQLDialect.SQLSERVER instead, when running your query on SQL Server. The LIMIT 10 syntax will then be correctly translated to TOP 10.
jOOQ Professional Edition vs jOOQ Open Source Edition
From our posted error messages, it is not quite clear how you really configured your jOOQ integration, but if you're using DSL.using(Connection) without explicitly specifying the SQLDialect, and jOOQ doesn't correctly "guess" the appropriate SQLDialect, this can mostly be because of one of two reasons:
You're using some non-standard JDBC URL, which jOOQ doesn't recognise. It thus uses SQLDialect.DEFAULT, instead, which produces the wrong SQL syntax for your.
You're using the jOOQ Open Source Edition (Maven groupId org.jooq) instead of the jOOQ Professional Edition (Maven groupId org.jooq.pro, to be installed manually, as it is not distributed via Maven Central), which would also lead to jOOQ using SQLDialect.DEFAULT.
Notice: this can also happen by accident, e.g. as a transitive dependency that is being pulled in via Spring Boot or some other framework that already depends on the jOOQ Open Source Edition. In that case, you have to make sure to exclude that transitive dependency from ending up on your classpath. In Maven, you can display all your dependencies using mvn dependency:tree
Any suggestions how to restructure this simple query?
Hitting a SQL Server Database using DAO via VB6 (updated old code to work with new database) and somehow this query in one of the apps is giving fits.
Select I.sType, Count(I.BarcodeID) AS CountOfID
FROM (SELECT DISTINCT sType, BarcodeID From [Ready]) as I
GROUP BY I.sType
ORDER BY sType
I've pasted the query into SQL Enterprise Manager and it runs just fine as expected. It worked fine hitting the original Access DB. But somehow the DAO via ODBC hitting the SQL Server is generating:
"The Microsoft Jet database engine cannot find the input table or query"
Things I've tried:
Removing the ()
Removing "as I" and "I." notation.
Brackets around [Ready] and without (thinking it might be reserved
keyword).
Confirmed that the connection is to the ODBC for Sql Server (this connection is used for other queries too.
Checked SQL profiling tool and the query is making it to the server (edited, I was checking the wrong tool on SQL Express)
EDIT: just to sate everyone's concern that I'm not really hitting SQL Server, I edited the SQL command to an even simpler
SELECT DISTINCT sType, BarcodeID From [Ready]
and it works correctly ON the same connection, so the connection is 100% confirmed to be SQL Server, the error message is in error (reported "Access").
So the problem is with no doubt the query FROM a query.
UPDATE:
Definitely confirmed my suspicions that the query, albeit a normal one, is not working with ADO-> ODBC-> Sql Server.
The first step SQL is doing is trying to validate the columns, etc.. of the "from" table (which in this case is not a table, but a query itself).
When I run a basic SELECT DISTINCT sType, BarcodeID From [Ready] SQL checks the columns, keys, indexes, etc of the table called "Ready" (exec sp_special_columns N'Ready',NULL,NULL,N'V',N'T',N'U'), then proceeds to return the results.
When I use a subquery, SQL is firing the same check on the table def, but for a table called SELECT DISTINCT sType, BarcodeID From [Ready] which of course does not exist and it returns an error (exec sp_special_columns N'SELECT DISTINCT sType, BarcodeID From [Ready]',NULL,NULL,N'V',N'T',N'U'). VB6/ADO is reporting correctly that SQL says the table is not found. So apparently this query from a query stumps the capabilities of ADO->ODBC...
since the issue is clearly the Select FROM (Select From) structure of querying a query being incompatible with ADO->ODBC->SQL Server, my solution was simply to make the subquery a view in SQL and alter the query to select from that.
(My environment: Windows 7 x64 and Server 2008, EclipseLink 2.5.2, I've tried the following with JTDS and the MS JDBC driver, and with MS SQL Server Express 2008 and 2012.)
I'm doing a paginated query in a table with anywhere from 5-50 million rows, with about 5 million rows matching the filter criteria. The following is the paginated query I'm using to display this data in the UI 25 rows at a time. The pagination is working properly - the list contains just 25 rows for each page. However, the query takes 24 seconds to return 25 rows, which seems long.
My goal is to log the generated SQL, so I can see exactly how JPA is accomplishing the pagination in SQL Server 2008 vs 2012. But the generated SQL doesn't include anything to do with pagination, which makes me wonder what else I'm not seeing in the generated SQL.
The query:
CriteriaBuilder cb = JPA.em().getCriteriaBuilder();
CriteriaQuery<RGHICarrierPull> cq = cb.createQuery(RGHICarrierPull.class);
Root<RGHICarrierPull> from = cq.from(RGHICarrierPull.class);
CriteriaQuery<RGHICarrierPull> select = cq.select(from);
// Add filter/sort predicates to "predicates"
...
select.where(predicates);
// Apply pagination
records.setFirstResult((page-1)*limit);
records.setMaxResults(limit);
// Get data
List<RGHICarrierPull> lst = records.getResultList();
To log the generated SQL programatically:
// Log the sql for this query
Session session = JPA.em().unwrap(JpaEntityManager.class).getActiveSession();
DatabaseQuery databaseQuery = ((EJBQueryImpl)records).getDatabaseQuery();
databaseQuery.prepareCall(session, new DatabaseRecord());
System.out.println(databaseQuery.getSQLString());
The logged SQL:
SELECT t1.SHIPTO_ZIP, t1.WHSE, t1.ANYNBR1, t1.ANYTEXT1, t1.CREATE_DATE_TIME, t1.
MOD_DATE_TIME, t1.PULL_TIME, t1.PULL_TIME_AMPM, t1.PULL_TRLR_CODE, t1.USER_ID,
1.SHIP_VIA FROM Ship_Via t0, RGHI_Carrier_Pull t1 WHERE ((t1.WHSE = 'WHSE1') AND
(t0.SHIP_VIA = t1.SHIP_VIA)) ORDER BY t0.SHIP_VIA ASC, t1.SHIPTO_ZIP ASC
Obviously, this is not a paginated query, so if I run this query directly, it runs for over a minute and returns all 5 million rows. I get the same results if I use persistence.xml settings to log all JPA queries, and also if I log the SQL from MS SQL Server.
Is this the actual generated SQL? I see two possibilities:
This is the full generated SQL, but EclipseLink is doing something else to accomplish the pagination.
EclipseLink is logging this generated SQL prior to the pagination stuff being added to it
Try setting the log level in EclipseLink to Finest, and check the database platform that is being used. EclipseLink logging will also show what is sending to the database. This should log the same SQL as what you get from the getSQLString(), but allows you to validate you are executing the correct api, and the initial start up logging will show if the platform being used matches your database, otherwise it will need to be specified using the target-database property: http://www.eclipse.org/eclipselink/documentation/2.4/jpa/extensions/p_target_database.htm
EclipseLink will use pagination within the generated SQL as described here http://wiki.eclipse.org/EclipseLink/Examples/JPA/Pagination if the plaform supports it, otherwise it resorts to using JDBC api to limit the results sent across, and then jump to the first result in the returned resultset, which is less efficient then if pagination is done entirely in the database.
EclipseLink (at least up to the current version 2.6.1) supports neither SQL Server 2012 pagination in the form of OFFSET-FETCH syntax nor older SQL Server TOP syntax, check out EclipseLink Database Support. Instead EclipseLink internally uses JDBC feature Statement.setMaxRows() which essentially discards excessive rows from the returning ResultSet. And there is no plans to support that in the future versions so far.
You can try to implement this manually extending the SQLServerPlatform and overriding method printSQLSelectStatement() similarly to how it is done in PostgreSQLPlatform.printSQLSelectStatement(). The working prototype is here: https://github.com/roman-sinyakov/eclipselink/blob/master/SQLServer2012Platform.java.
I have created a linked-server definition according to the article at :
http://www.ideaexcursion.com/2009/01/05/connecting-to-oracle-from-sql-server/
My aim is to transfer rows to tables at Oracle 11gR2.
After creating linked server, whenever I try to select a table using a query like :
SELECT *
FROM [192.168.1.188]..[ESIPARIS].[T_ERROR_LOG]
I get the error below :
Msg 7356, Level 16, State 1, Line 1
The OLE DB provider "OraOLEDB.Oracle" for linked server "192.168.1.188"
supplied inconsistent metadata for a column. The column "EVENT_OBJECT"
(compile-time ordinal 2) of object ""ESIPARIS"."T_ERROR_LOG"" was reported
to have a "LENGTH" of 50 at compile time and 100 at run time.
One more thing is that it duplicates field names whenever a select statment is prepared by "Sql Server Management Studio", some fields are duplicated as below :
SELECT [EVENT_DATE]
,[EVENT_DATE]
,[EVENT_DATE]
,[EVENT_DATE]
,[EVENT_OBJECT]
,[EVENT_OBJECT]
,[EVENT_OBJECT]
,[EVENT_OBJECT]
,[MESSAGE]
,[MESSAGE]
,[MESSAGE]
,[MESSAGE]
,[EVENT_ID]
FROM [192.168.1.188]..[ESIPARIS].[T_ERROR_LOG]
I would be very happy to hear from you about any ideas, thank you for your concern,
Best Regards,
Kayhan YÜKSEL
There are a number of scenarios which might throw this error:
your distributed query in SQL Server references a view with an underlying table in Oracle with a primary key column created in a certain way, Find out more
there's a bug when the querying a view with numeric columns. Find out more
it may be a problem with driver incompatibility, such as using the MS OleDB driver instead of the one Oracle provides.
If it isn't the driver one possible workaround is to use OPENQUERY. Otherwise. this support note contains general information on troubleshooting linked server and Oracle.
(This problem is a fairly generic one, so it turned out that the actual resolution was none of the things I suggested. I'm incorporating #kayhanyüksel's solution in the body of this response for the sake of completeness.)
Solved it with changes at listener and tnsnames. We are now able to connect from SQL Server to Oracle 11gR2 (running on 64 bit Red Hat Enterprise Linux 5.4 ) and vice versa. Documents followed are
- Making a Connection from Oracle to SQL Server
- The Oracle Gateways documentation
I had the same problem: The column ...... was reported
to have a "LENGTH" of 50 at compile time and 100 at run time. and duplicate column names when selected.
while i was trying to run a query in MS SQL from an ORACLE 11g database
I used the follownig type of query and it worked !
DECLARE #TSQL varchar(8000)
SELECT #TSQL = 'SELECT * FROM OPENQUERY(MyLinkedServer,''SELECT * FROM TableName'')'
EXEC (#TSQL)
where MyLinkedServer is the name of the linked server and
TableName is the name of the table.
here you have the link to the article that helped me: http://support.microsoft.com/kb/314520
Old thread but it may be useful to someone.
When I recently encountered this error, using as provider the MS OleDB driver instead of the Oracle OleDB provider solved the problem.
I have the same issue with 11g client but it was disappeared with client version 12 which works for me is using OPENQUERY and to_char with the field that makes problem.
I confirm that SQL management studio (no matter what version) gives many duplicated field. The only installing of last driver version we can have consistent queries. I hope it can be useful for you!