Hsqldb rownum in UPDATE statement - hsqldb

Hallo, I've a problem with this query :
update EXAMPLETABLE set FLAG = 1 where FLAG = 0 and rownum < 10;
This query is working in Oracle (it updates exactly 9 rows), but not in my testcase with hsqldb (the statement updates ALL the rows in EXAMPLETABLE).
I'm using also
SET DATABASE SQL SYNTAX ORA TRUE;
in hsqlDb generation script.
I'm using hsqlDb in-memory only.
Is this feature not implemented in hsqlDb?
Thanks,
Roberto

This feature is not implemented in HSQLDB. It may be supported in ORACLE mode in the near future. (update: now supported in 2.2.6 and later versions).
There is a problem in principle about this type of statement. As the rows could be returned in any order, an update is performed on an almost arbitrary subset of rows with the given FLAG setting.

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.

Change parameters to fixed values in offset\fetch clause

I am using NHibernate with Progress OpenEdge 11.3 Update 2 ODBC Driver. The driver (or OpenEdge) does not allow parameters in offset\fetch clauses. The offset\fetch clause must contain fixed values. According to the documentation and this article:
http://knowledgebase.progress.com/articles/Article/2916
Not allowed:
select * from PUB.customer offset ? rows fetch next ? rows
Execption:
ERROR [HY000] [DataDirect][ODBC Progress OpenEdge Wire Protocol driver][OPENEDGE]Syntax error in SQL statement at or about "? rows fetch next ? rows only " (10713)
Allowed:
select * from PUB.customer offset 10 rows fetch next 10 rows
How can I modify NHibernate's behaviour to use fixed values instead of parameters, when using Linq?
var customers = session.Query().Skip(10).Take(10).ToList();
Maybe someone can point me to the right direction. I have already downloaded the NHibernate sources and debugged them, but I could not find the right place to replace the parameters.
Thanks!
I found a solution:
I set UseVariableLimits to false within my custom Nhibernate ODBC dialect. Furthermore, I installed the NHibernate 4.0.0.-Alpha2 nuget package.
This fixed the problem. Hope that NHibernate 4.0.0 will be stable and released soon.

Determine "version" of DB from Liquibase tables

We use Liquibase for configuration management across multiple MS SQL Server DB instances. If all DBs have executed all available Liquibase scripts, is the following a reliable query to confirm that all DBs are in sync? I am looking for a way to do this from a DB script and not Maven or any other command line utility.
select top 1 ID from DATABASECHANGELOG
order by DATEEXECUTED desc
That might work for really simple scenarios, but if your changelogs have any kind of 'conditional' parts you are going to need some more logic than that.
What you really want to know is whether the set of changes applied to each database is the same. Since changesets are identified by id+author, you should get both those columns from DATABASECHANGELOG and then do set comparison on those to see that the sets were exactly equal.
I would suggest tagging your database. Two supported mechanisms:
tagDatabase refactor command, contained in a changeset
command line tag option
I personally would favor the first option so that the versioning is built into the changeset files. The second option is useful when performed as part of your application's upgrade process (Create a rollback marker).
Finally, once your database is tagged the latest version can be retrieved using SQL:
SELECT TOP 1 cl.tag
FROM DATABASECHANGELOG cl
WHERE cl.tag is not null
ORDER BY 1 DESC
Obviously this approach assumes that your tag strings have a numeric component, so that they sort as expected.
Besides the conditional changeSets that #SteveDonnie mentioned, the order that changeSets execute in can vary depending on how and when you are updating your changelog and database. For example, if you have changeSets A,B and then developer X adds C and developer Y updates D then X's order is A,B,C and Y's order is A,B,D. When they both merge their changes together the final order may be A,B,C,D and when X runs the final version his order will be A,B,C,D but Y's final order will be A,B,D,C.
Y's database will be fully up to date, but a SELECT TOP 1 will return "C" for him even though you were expecting "D". It may or may not be a scenario you run into, but is another reason why a simple single row select will not tell you if databases are up to date or not.
Liquibase does have a "status" command you can run against a database and a changelog and it will return whether the database is up to date or not.

Hibernate setMaxResults() not working for Sybase database query

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.

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.