I'm using org.skife.jdbi.v2.unstable.BindIn in my prepared statements. It works as expected unless I try to concatenate the parameter in the query.
Below are 3 queries. The first 2 queries work as expected, but the third query gives this error:
A SELECT statement that assigns a value to a variable must not be
combined with data-retrieval operations
SELECT
name
FROM
myTable WITH(NOLOCK)
WHERE
ID in ( <ids> )
declare #query VARCHAR(MAX)
select #query = '
SELECT
name
FROM
myTable WITH(NOLOCK)
WHERE
ID in (1, 2, 3)'
execute(#query)
declare #query VARCHAR(MAX)
select #query = '
SELECT
name
FROM
myTable WITH(NOLOCK)
WHERE
ID in (' + <ids> + ')'
execute(#query)
Related
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 ...
Previous output
SQL query -
select
employeeid,FamilyPay,IsActive,
stuff((
select ',' + u.IndividualPay
from yourtable u
where u.IndividualPay = IndividualPay
order by u.IndividualPay
for xml path('')
),1,1,'') as IndividualPay
from yourtable
group by EmployeeID,FamilyPay,IsActive
output :-
Desired output
Can someone help me changing this in Hibernate query ?
It would be a misuse of HQL to replicate that SQL query. HQL is a query language for Hibernate entities, not a replacement for SQL, thus you need to work at the level of Hibernate entities.
You can use #Formula to directly bind the subquery result to a entity field:
#Formula("stuff(( select ',' + u.IndividualPay from yourtable u where u.IndividualPay = IndividualPay order by u.IndividualPay for xml path('') ),1,1,'')")
private String individualPay;
When Hibernate generates the query, it will insert this SQL fragment into the generated SQL.
It is more important to define your entity correctly. The HQL should be simple.
I need some help writing an SQL statement for the below requirement.
I have list of employee_id which I need to check whether they are exist in the DB or not from the java layer I want to use one query for this.
Sample query:
SELECT *
FROM employee
WHERE employee_id IN (1001,1002,1002,10000004).
In this query 10000004 does not exist in DB.
One approach in my mind is to use the below query:
SELECT Count(employee_id)
FROM employee
WHERE employee_id IN (1001,1002,1002,10000004).
Then check the list size and the result from the query in java layer. But I don’t want this because I need all those employee_id which does not exist in DB.
declare #employeeids varchar(1000) --to store ids as comma seperated string
declare #tmpEmployee table (employee_id varchar(50)) --temp employee table to store ids from string
declare #pointer int
select #employeeids = '1001,1002,1002,10000004' --list of ids to check against database
while (charindex(',', #employeeids, 0) > 0)
begin
set #pointer = charindex(',', #employeeids, 0)
insert into #tmpEmployee (employee_id)
--remove white spaces if exists
select ltrim(rtrim(substring(#employeeids, 0, #pointer)))
set #employeeids = stuff(#employeeids, 1, #pointer, '')
end
insert into #tmpEmployee (employee_id)
select ltrim(rtrim(#employeeids))
select r.employee_id -- required ids which does not exists in database
,e.employee_id
from #tmpEmployee r
left join employee e on r.employee_id=e.employee_id
where e.employee_id is null
If you are using Oracle, then this link may help you. It's all about usage of built in SYS.DBMS_DEBUG_VC2COLL function
Exist a very bad way to do that is this:
SELECT * FROM (SELECT 5930 id UNION SELECT 8109 id
UNION SELECT 8110 id UNION SELECT 8115 id UNION SELECT 8112 id
UNION SELECT 8113 id UNION SELECT -1 id) b
WHERE b.id NOT IN (SELECT f.id FROM employee f)
I recommed you do that in other way.
When using a Java PreparedStatement, the question-mark placeholders aren't being detected. It would throw an error "The column index is out of range: 1, number of columns: 0" when invoking statementName.setLong(1, 123). My example is from Postgres 8.4, but the problem occurs before the SQL has a chance to make it to the SQL server.
After comparing against some working prepared statements, I realized that the broken one contained a subquery similar to:
SELECT * FROM (
SELECT DISTINCT (name)
id,
name
FROM MyTable
WHERE id > ?
ORDER BY name) AS Level1
ORDER BY 1
The solution that worked for me was to convert the query to a CTE (Common Table Expression). The revised query looks like this:
WITH Level1 AS (
SELECT DISTINCT (name)
id,
name
FROM MyTable
WHERE id > ?
ORDER BY name)
SELECT *
FROM Level1
ORDER BY 1
In JDBC, the parameter indexes for prepared statements begin at 1 instead of 0.
I have a query that worked for me when I was using Mysql.
Now I get this error on Oracle :
ORA-00979: not a GROUP BY expression
This is the query:
SELECT o.neNesId, COUNT(o)
FROM ParNe AS o
WHERE o.neBanId = :neBanId
GROUP BY o.neNesId
Any ideas why I have this error?
Your query is:
SELECT o.neNesId, COUNT(o)
FROM ParNe AS o
WHERE o.neBanId = :neBanId
GROUP BY o.neNesId
My guess is that o.o is not a valid field. So, you have a table name where a column name is expected.
Try this instead:
SELECT o.neNesId, COUNT(*)
FROM ParNe AS o
WHERE o.neBanId = :neBanId
GROUP BY o.neNesId
Or replace the * with a valid column name.
use count(*) . count(o) is used in hibernate not in sql query
You need to select count(*) or count(1) as in Gordon's example. If you insist on using your query syntax, which is not necessary at all then try this:
SELECT neNesId, count(o) AS o_cnt
FROM
( -- your query here --
SELECT 1 neNesId, 2 AS o FROM dual
)
GROUP BY neNesId
/