How should I use COLLATE in Hibernate Query - java

I'am trying to use COLLATE statement in a Hibernate SQL query but, it doesn't recognize the statement.
CONSULTA: FROM Articulos WHERE activo=0
and (codigodearticulo like '%CIN EMB%' COLLATE='Modern_Spanish_CI_AI'
or descripcion like '%CIN EMB%' COLLATE='Modern_Spanish_CI_AI'
or descripcionadicional like '%CIN EMB%' COLLATE='Modern_Spanish_CI_AI' )
and codigodelinea in
(select CODIGODELINEA from Lineas where CATAUTOPARTES='1')
And when app compile, Hibernate return this exception :
- line 1:107: unexpected token: COLLATE
- line 1:107: unexpected token: COLLATE
- line 1:107: unexpected token: COLLATE
- Error hibernate: unexpected token: COLLATE near line 1, column 107
I can't find the problem, in MSSQL Server it works fine.

Unfortunately HQL isn't a complete replacement for SQL, and doesn't seem to allow specifying Collation at all.
It can be specified on a Criteria query. See this answer

Instead of having in HQL:
String hql = "SELECT e" +
" FROM EntityJPA e" +
" WHERE e.mycolumn COLLATE 'utf8_bin' = 'VALUE'"
Query query = entityManager.createQuery(hql);
You can use a Native Query like this
String sql = "SELECT t" +
" FROM entity_table t" +
" WHERE t.mycolumn COLLATE 'utf8_bin' = 'VALUE'"
and execute it a a Native Query:
Query query = entityManager.createNativeQuery(sql);
This was the simpler solution by keeping in mind that native query create a dependency on the SQL language of the target database (mySQL in our case).
For us this was still acceptable as the possibility to use a different DB Engine is very low.

Related

Testing: Incompatibility between MySQL and H2

I'm trying to test my JPA native #Query with H2.
My native query is as follows:
#Query(
value = "SELECT * FROM accounts " +
" WHERE 'account_name' LIKE LOWER(CONCAT('%', COALESCE(:searchTerm, ''), '%')) ",
countQuery = "SELECT count(*) FROM accounts " +
" WHERE 'account_name' LIKE LOWER(CONCAT('%', COALESCE(:searchTerm, ''), '%')) ",
nativeQuery = true
)
When writing a unit test, I'm getting the following H2 error:
Caused by: org.h2.jdbc.JdbcSQLException: Table "ACCOUNTS" not found;
SQL statement: SELECT * FROM accounts WHERE 'aws_account_name' LIKE
LOWER(CONCAT('%', COALESCE(?, ''), '%')) limit ? [42102-197]
I can fix the H2 error by changing my SQL syntax to put table name in double-quotes:
#Query(
value = "SELECT * FROM \"accounts\" " +
" WHERE 'account_name' LIKE LOWER(CONCAT('%', COALESCE(:searchTerm, ''), '%')) ",
countQuery = "SELECT count(*) FROM \"accounts\" " +
" WHERE 'account_name' LIKE LOWER(CONCAT('%', COALESCE(:searchTerm, ''), '%')) ",
nativeQuery = true
)
HOWEVER, then my MySQL (actual non-test environment) complains:
Caused by: java.sql.SQLSyntaxErrorException: You have an error in your
SQL syntax; check the manual that corresponds to your MySQL server
version for the right syntax to use near '"accounts" WHERE
'account_name' LIKE LOWER(CONCAT('%', COALESCE('ab', ''), ' at line 1
How can I test this native query with MySQL and H2?
The reason I'm using native query instead of JPQL is because I need to search without case sensitivity and allow "contains" matching.
By default, MySQL recognizes a token enclosed in double quotes as a string literal, not an identifier (i.e. a table name or column name).
If we modify MySQL sql_mode to include ANSI_QUOTES, then a token enclosed in double quotes will be seen as an identifier. But this is going to cause a problem in SQL where string literals were enclosed in double quotes rather than the SQL standard single quotes.
If H2 compatibility mode is set to MySQL, then we should be able to use the normal MySQL backtick characters to escape identifiers. e.g
SELECT *
FROM `accounts`
^ ^
Also, MySQL isn't going to object to this construct:
WHERE 'aws_account_name' LIKE
^ ^
but enclosed in single quotes, MySQL sees the token 'aws_account_name' here as a string literal, not as a reference to a column.
If that's supposed to be a column name, we can use the MySQL backtick characters around a column reference.
To reduce confusion and make it easier on a future reader, we typically like to qualify column references, even where it isn't strictly required. For example, using a short table alias:
SELECT t.*
FROM `accounts` t
WHERE t.`aws_account_name` LIKE ...

MySQL Syntax Issue when using Accounts.UUID AND UUID =, with two tables

I'm having issues when using this:
WARN com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE Accounts.UUID = WarAccounts.UUIDAND Accounts.UUID = 'c7a00fe7-826d-46da-b4' at line 1
Here is the SQL:
SELECT
*
FROM
Accounts,
WarAccounts
WHERE
Accounts.UUID = WarAccounts.UUID
AND Accounts.UUID = ?
(Using prepared statements)
I'm very confused as to what is wrong with this to cause that issue, I've googled it but cannot find anything since this seems to be the correct way.
Server type: MySQL
Server version: 5.5.58-0ubuntu0.14.04.1 - (Ubuntu)
Wild ass guess:
In C# i would do this:
string query = "SELECT *" +
"FROM MYTABLE" +
"WHERE 1=1"
..to get your error..
Concat the string and you'll see the problem:
"SELECT *FROM MYTABLEWHERE 1=1"
The concatination should be:
string query = "SELECT * " +
"FROM MYTABLE " +
"WHERE 1=1 "
(see the spaces at the end of every line?)

Cannot query SQL Server table containing Arabic from my Java app using HQL

I'm working on a Java Swing application where I query a table in a SQL Server database. This table contains some data that is in Arabic, Chinese etc... But the problem is that I am not getting any results while using this query: (var can be Arabic or any other language):
from Table T where T.columnName like '%"+var+"%'
I did some searching and then tried the following:
from Table T where T.columnName like N'%"+var+"%'
I am getting this error message on NetBeans:
Exception in thread "AWT-EventQueue-0"
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: N near line 1
Can someone help me with this problem? I'm confused knowing that this same last query worked perfectly in SQL Server Management Studio.
The problem is that HQL != T-SQL, and you are mixing the two. HQL is pseudo-SQL and so does not understand the T-SQL-specific dialect handling of Unicode strings (i.e. the N-prefix on string literals).
So, it seems like you have two options:
HQL
Continue using createQuery as follows:
session.createQuery("from Table T " +
"where T.column like :fltr ")
.setParameter( "fltr", "%" + content + "%", StringNVarcharType.INSTANCE )
.list();
T-SQL
Switch to using createSQLQuery as follows:
session.createSQLQuery("select * from Table T where T.column like N'%" +
content + "%' ").list();
There might be more to do here, but I have no way to test it.
More info and examples can be found at: Hibernate ORM 5.2.4.Final User Guide:
HQL code above based on Example 334
StringNVarcharType type found in chart of 2.3.1. Hibernate-provided BasicTypes: Table 1. Standard BasicTypes
T-SQL code above based on Example 402 and Example 423
Declare your var as NVARCHAR, and remove the quotations.
FROM Table T WHERE T.columnName LIKE N'%' + var + N'%'
Use the following HQL:
String hql = "FROM Table T WHERE T.columnName LIKE CONCAT('%', :columnValue, '%')";
session.createQuery(hql)
.setString("columnValue", "Sample Value")
.list();

Run Oracle query from Java

I want to run the query: "DESCRIBE table_name;"
statement = this.connection.createStatement();
ResultSet rset = statement.executeQuery("DESCRIBE table_name");
and I got this error:
" java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement"
what is the problem?
DESC[RIBE] is a SQL*Plus command, not a SQL statement. The DESC command queries the Oracle data dictionary, something like:
select COLUMN_NAME, DATA_TYPE
from USER_TAB_COLUMNS
where TABLE_NAME = 'YOUR_TABLE'
DESC is a SQL*Plus command. SO, you cannot use it via JDBC/ODBC.
An alternative can be like this below.
select RPAD(COLUMN_NAME,30)||' '||DATA_TYPE||'('||DATA_LENGTH||')' as descr
FROM all_tab_cols
WHERE TABLE_NAME = UPPER('YOUR_TABLE') and owner=UPPER('SCHEMA_NAME');
all_tab_cols is a data dictionary table(view) which contains the table metadata
Oracle's Reference
describe user2.flights;
Here user2 is database name and flights is table name. Try this.
Or use next query
select *
from user_tab_columns
where table_name = 'MY_TABLE'
order by column_id;
Use this query.
column_id is the "order" of the column in the table.
You should ensure that 'MY_TABLE' is capitalised unless you've been adding tables with casing ( a bad idea ) in which case you need to use something like = "MyTable"

Using datediff in sql jdbc query

I'm attempting to create a JDBC query with the following statement
String query = "SELECT COLUMN1,DATECOLUMN2 FROM tableName +
"where datediff(d,DATECOLUMN2,getdate()) <= 1";
st = conn1.createStatement();
rs = st.executeQuery(query); //receiving error here
I am receiving the following error message
java.sql.SQLException: "d" is not a recognized table hints option. If it is intended as a parameter to a table-valued function or to the CHANGETABLE function, ensure that your database compatibility mode is set to 90.
I'm sure the query isn't recognizing the datediff function for some reason I am not sure why since i was previously using HQL in the same application and retrieving the values.
In an attempt to use an alternative function I used
{fn TIMESTAMPADD( SQL_TSI_DAY, 1, CURRENT_TIMESTAMP)}
but it also failed I later on found that this is only used for Derby Database's
Can someone assist me in using the proper sql function to compare a date with the current date using JDBC
String query = "SELECT COLUMN1,DATECOLUMN2 FROM tableName "+
"where datediff(day,DATECOLUMN2,getdate()) <= 1";
You have a comma before from. Based on the error messages you are running this against SQL server.
String query = "SELECT COLUMN1,DATECOLUMN2 FROM tableName "
+" where datediff(d,DATECOLUMN2,getdate()) <= 1";
The comma after the "d" should be a dot:
where datediff(d.DATECOLUMN2,getdate())
--------------- ^ dot here
The posted snippet doesn't have a closing double quote between tableName and +, but I figure that is just a typo. However, in your real code, where precisely is the double quote? Is it directly after tablename, like this
String query = "SELECT COLUMN1,DATECOLUMN2 FROM tableName" +
or after the space that follows tablename, like this
String query = "SELECT COLUMN1,DATECOLUMN2 FROM tableName "+
It is very likely the former, because in that case the resulting query would look exactly the way as to cause the error you are getting. Take a look at this:
SELECT COLUMN1,DATECOLUMN2 FROM tableNamewhere datediff(d,DATECOLUMN2,getdate()) <= 1
You can see that where merges with the table name and datediff becomes an alias. What follows is interpreted as table hints. (You can specify table hints without WITH in older versions of SQL Server/older compatibility levels.) Consequently, SQL Server stumbles over d, as that is indeed an incorrect table hint.

Categories