I want to fetch data from exasol but only facing this issue when I use limit clause in query.
If i hardcode the limit values in query and don't use prepared statement for then it works fine. But when I try to set int for limit clause in prepared statement it gives me exception
public static final String FROM_DWB_DATA = "SELECT * FROM DWB_DATA a \n"
+ "INNER JOIN DWB_CONN b \n"
+ "ON a.SOURCE_ID=b.ID\n"
+ "WHERE b.PROJECT_ID=? ORDER BY a.TABLE_NAME LIMIT ? , ?";
//and in Prepared statement i am setting these values
PreparedStatement ps = getSQLConnection(projectId, conid)
.prepareStatement(FROM_DWB_DATA_TABLE);
ps.setString(1, projectId);
ps.setInt(2, 0);
ps.setInt(3, 2);
java.sql.SQLException: non-negative integer value expected in LIMIT clause
I guess, it adds your values in quoted form: LIMIT '0', '2'.
Try to build query string normally and run it as simple non-prepared query.
Related
I use prepared statements to read/write data in my DB (SQLite). In my table INVENTORY, there are records which have null value in the column paleta (the column is defined as VARCHAR in the table). I want to select these records and I tried:
sq = "SELECT * FROM INVENTORY WHERE paleta = ? AND product = ? AND lot = ?";
//...
stm = c.prepareStatement(sq);
stm.setNull(1, java.sql.Types.VARCHAR);
stm.setString(2, "theIdOftheProduct");
stm.setString(3, "theLotOftheProduct");
ResultSet rs = stm.executeQuery();
The above query doesn't return anything.. I removed the paleta = ? and I get the records I want.. How can I define the query like SELECT * FROM INVENTORY WHERE paleta is null etc.. using the query parameters?
What you are trying to do is equivalent to writing SELECT * FROM INVENTORY WHERE paleta = NULL ..., which doesn't work.
Since you are essentially searching for rows having a constant value in the paleta column (which happens to be NULL), you can eliminate the first query parameter and explicitly check for null:
sq = "SELECT * FROM INVENTORY WHERE paleta IS NULL AND product = ? AND lot = ?";
stm = c.prepareStatement(sq);
stm.setString(1, "theIdOftheProduct");
stm.setString(2, "theLotOftheProduct");
I found my answer in https://stackoverflow.com/a/4215618/1052284
You'll have to decide upon an unused value. I simply kept it at '' since I don't have empty values.
sq = "SELECT * FROM INVENTORY WHERE IFNULL(paleta, '') = ? AND product = ? AND lot = ?";
//...
stm = c.prepareStatement(sq);
stm.setString(1, ""); // '' for NULL, otherwise a specific value
stm.setString(2, "theIdOftheProduct");
stm.setString(3, "theLotOftheProduct");
But beware if you many queries, it's VERY slow. I clock in at about 4000 times slower, on average, than queries without IFNULL. ~50ms instead of microseconds.
String sqlInsertBeacon = "INSERT INTO `beacon` (zone_id, location) VALUE ('(SELECT id FROM zone WHERE GeographicalID = '" + geometry3 + "')', Point(" + x_coordinate + "," + y_coordinate + "))";
System.out.println("The SQL query is: " + sqlInsertBeacon); // Echo for debugging
int countInserted3 = stmt.executeUpdate(sqlInsertBeacon);
System.out.println(countInserted3 + " records inserted.\n");
When I run the above code, the build is successful but the program stops when it reaches the execute line. I am entering using this sql query to insert data into a mysql database. I am not sure where the error is in my query? Can anyone suggest an alternative way or find the mistake?
The output of the program is this, as you can see the program, stops running after the second line:
The SQL query is: INSERT INTO table
(zone_id, location)
VALUES
((SELECT id FROM zone WHERE GeographicalID = '6311599'), Point(-121.9453802,37.3256131) )
;
BUILD SUCCESSFUL (total time: 6 seconds)
For additional information incase it helps:
The stmt, is created like this:
try (
// Step 1: Allocate a database 'Connection' object
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/adhwere2?useSSL=false", "root", "your_new_password"); // MySQL
// Step 2: Allocate a 'Statement' object in the Connection
Statement stmt = conn.createStatement();) {
and the catch exception is :
} catch (SQLException ex) {
}
Try something like this:
String sqlInsertBeacon = "INSERT INTO `beacon` (zone_id, location)" +
" VALUES ( (SELECT id FROM zone WHERE GeographicalID = '" + geometry3 + "'), Point(" +
x_coordinate + "," + y_coordinate + "))";
Just removed the apostrophes aroung the inner SELECT and replaced VALUE with VALUES...
The problem was because the sub-query was returning more than one result, and printing out a stack trace helped debug this error. Using Limit 1 in the sub query also solved this issue.
please use query according to this syntax:
INSERT INTO table
(column1, column2, ... )
VALUES
(expression1, expression2, ... ),
(expression1, expression2, ... ),
...;
your table name is in single quotes and its VALUES not value mind these small things
Correct INSERT INTO SELECT statement looks like this:
INSERT INTO table2
SELECT * FROM table1
WHERE condition;
And you can use PreparedStatement to set parameters in your query.
I am currently trying to use a DECLARE clause in a preparedStatent with jdbc. The code that I wrote is:
statement.executeUpdate(" declare #variable int set #variable = "+timer+" INSERT INTO table1 values (ip, protocol, counter, timer) SELECT ip,protocol,counter,#variable FROM table2 ORDER BY counter DESC LIMIT 5 OFFSET 0 ;");
What I'm trying to get is to create a new table (that is table1) which includes the top 5 from table2 (every 5 secs e.g), with a predefined interval. The interval is the timer variable. The timer variable is passed through a method.
Note: I don't know if it makes any difference to use preparedStatement. I tried both.
Assuming you need to create a new table from a select, then you should use this query instead:
CREATE TABLE table1 SELECT ip,protocol,counter,#variable FROM table2 ORDER BY counter DESC LIMIT 5 OFFSET 0
But if you do this in Java and using PreparedStatement then you can pass the value of #variable as a parameter, thus getting rid of the previous query. So, your query will look like this in Java code:
String sql =
"CREATE TABLE table1"
+ " SELECT ip,protocol,counter,?"
+ " FROM table2"
+ " ORDER BY counter DESC"
+ " LIMIT 5 OFFSET 0";
Assuming you already have the table table1 created and you're just adding the latest results into it from table2, then the query will look like this:
INSERT INTO table1 values (ip, protocol, counter, timer) SELECT ip,protocol,counter,#variable FROM table2 ORDER BY counter DESC LIMIT 5 OFFSET 0
Again, you can pass the value of #variable as a parameter. The query will look like this in Java code:
String sql =
"INSERT INTO table1 (ip, protocol, counter, timer)"
+ " SELECT ip,protocol,counter,?"
+ " FROM table2"
+ " ORDER BY counter DESC"
+ " LIMIT 5 OFFSET 0";
Then, you will prepare the query like this:
PreparedStatement pstmt = con.prepareStatement(sql);
//setting your variable as the parameter in the query
pstmt.setString(1, timer);
In the end, you will use PreparedStatement#execute or PreparedStatement#executeUpdate:
//the former query is a DDL query
pstmt.execute();
//the latter query is a DML query
pstmt.executeUpdate();
I have an SQL query that i am going to run using a PreparedStatement, and it is
UPDATE tbl_HitsCounter SET count = ? WHERE keyid = (SELECT id FROM tbl_HitsMaster WHERE sitename = '?')
Now when i set the 2nd paramater, which is a string value, i am getting a strange SQLException.
preparedStatement.setInt(1, 99);
preparedStatement.setString(2, masterKey);
As the setString() method is executed, i am getting an SQLException
The column position '2' is out of range. The number of columns for this ResultSet is '1'.
I have no idea what this is about, i havent even executed the executeUpdate() method.
There is only one placeholder in your SQL but you are trying to assign a value for the second. Your problem is that you have quoted the second placeholder, your SQL should look more like this:
UPDATE tbl_HitsCounter
SET count = ?
WHERE keyid = (
SELECT id
FROM tbl_HitsMaster
WHERE sitename = ?
)
Note the lack of quotes in sitename = ?. This is a placeholder: ?. This is an SQL question mark string literal: '?'.
I have created table with 3 fields language,country,install type. When I write a query to print the maximum occuring value in each of the field, I am getting a weird problem.Can anyone say the reason.Here is my code.
PreparedStatement ps1= null;
ps1 = conn.prepareStatement("desc Configuration");
ResultSet rs1=ps1.executeQuery();
while(rs1.next()) {
System.out.print(rs1.getString(1)+":");
PreparedStatement ps2= null;
ps2 = conn.prepareStatement("select ? from Configuration c1 "+
" group by language "+
" having count(*) >= all " +
" ( select count(*) from Configuration c2 "+
" group by language )");
ps2.setString(1,rs1.getString(1));
ResultSet rs2=ps2.executeQuery();
while(rs2.next())
System.out.print(rs2.getString(1));
System.out.println();
}
The output I am getting here is language:language But the output what I am expecting is
language:english like that. I am getting later output if i replace '?' with language in the prepare statement.But if i give the same with ? I am getting what ever I have given for ps2.setString.
Why is this happening. Any solutions?
? in prepared statements is not a placeholder for textual substitution, it's a parameter, therefore its value is always interpreted as data, not as an arbitrary part of query syntax.
So, in this case the actual query being executed is an equivalent of select 'language' from ....
If you need to substitute parts of the query other than data, you have to use concatenation (beware of SQL injections!):
ps2 = conn.prepareStatement("select "
+ rs1.getString(1)
+ " from Configuration c1 group by language having count(*) >= all( select count(*)from Configuration c2 group by language )");
You can't set column names using a PreparedStatement. You can only set column values.
Instead of using this approach, you will have to build the sql yourself using concatenation, for example:
String sql = "select "+ rs1.getString(1) + " from Configuration c1 group by language having count(*) >= all( select count(*)from Configuration c2 group by language)";
The '?' mark in ps2 is recognized as literal-string. Not as a column name.