I am a bit baffled by this as I'm sure I have done it a hundred times but from this snippet of JDBC prepared statement:
"SELECT {0} FROM " +
"(select a.* " +
"from TABLE a " +
"inner join TABLE p ON " +
"and p.AS_OF_DT = TO_DATE(?, 'yyyyMMdd')";
...
pStmt.setString(1, dateAsString);
I am getting
java.sql.SQLSyntaxErrorException: ORA-00904: "YYYYMMDD": invalid identifier
I can reproduce the error in TOAD by removing the quotes around YYYYMMDD.
What do I need to do inside the prepared statement String to prevent this?
I have tried
playing with the upper/lowercase of YYYYMMDD
Ensuring the dateAsString is in the right format
Escaping the quotes like ''YYYYMMDD'' and '''YYYYMMDD'''
Related
I'm having a problem with this query of mine. I've spent almost an hour trying to correct it but still getting an error.
Heres my code:
sql = "INSERT INTO tbl_case \n" +
"(Case_ID, Employee_ID, Patient_ID, Chief_Complaint, Date) \n" +
"VALUES \n" +
"(\n" +
" '',\n" +
" 'EMP0001',\n" +
" '(SELECT Patient_ID from tbl_patient WHERE ID_no = '"+getPatient_ID()+"')',\n" +
" '"+txtcc.getText()+"',\n" +
" '"+time+"'\n" +
")";
dp.sop("Query 'Create Case': "+sql);
dp.Insertion(sql);
Note: dp stands for a class I inherited the methods from. dp.Selection is a simple executeQuery I made for retrieving data. dp.Insertion is for updating.
Here is the output of the query in String:
Query 'Create Case': INSERT INTO tbl_case
(Case_ID, Employee_ID, Patient_ID, Chief_Complaint, Date)
VALUES
(
'',
'EMP0001',
'(SELECT Patient_ID from tbl_patient WHERE ID_no = '10000201117')',
'Head Ache',
'2016-01-30 09:55:27'
)
and the error is a mysql syntax error near:
'10000201117)',
'Head Ache',
'2016-01-30 10:07:08'
)' at Line 7
anyone spotted whats wrong? I'm using mysql from xampp.
Since (SELECT Patient_ID from tbl_patient WHERE ID_no = '10000201117') is in single quotes you might want to try putting 10000201117 in double quotes.
For example:
'(SELECT Patient_ID from tbl_patient WHERE ID_no = "10000201117")'
I don't think you need to surround the SELECT statement with quotes.
As it is now, this part '(SELECT Patient_ID from tbl_patient WHERE ID_no = ' is interpreted as a value instead of part of a query.
Try: (SELECT ...) instead of '(SELECT ...)'
try(Connection dbConnection = DBConnectionManager.getIntakeConnection();
PreparedStatement preparedStmtSetMaxStrikeId = dbConnection.prepareStatement(
"SELECT MAX(strike_id) FROM strike WHERE 'SELECT p.party_type_id,"
+ "p.csa_score,p.party_tn,p.rec_create_date,"
+ "s.strike_id, s.strike_date, s.strike_level, s.strike_status,
s.appealable,s.appeal_status,s.rec_change_date,s.event_id,
s.is_email_processed,s.policy_id"
+ "FROM strike s "
+ "INNER JOIN parties p"
+ "ON p.party_id = s.party_id"
+ "WHERE p.account ='"+appealStatus.getSubscriberId()
+"'AND strike_status = '"+OCIRISConstants.STRIKE_STATUS_ACTIVE+"' ");)
The error is below.
Integers in the error are subscriber ids.
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 '0957936101205'AND strike_status = 'ACTIVE'' at line 1
The error message says:
near '0957936101205'AND strike_status = 'ACTIVE'' at line 1
It's actually identifying the 0 following the ', which ends the text literal started in the first line, because this is bad SQL:
SELECT MAX(strike_id) FROM strike WHERE '...'0957936101205'AND strike_status = 'ACTIVE'
-- ^^ BAD
Here is the code annotated with comments:
try(Connection dbConnection = DBConnectionManager.getIntakeConnection();
PreparedStatement preparedStmtSetMaxStrikeId = dbConnection.prepareStatement(
"SELECT MAX(strike_id) FROM strike WHERE 'SELECT p.party_type_id,"
// ^ What is this? Even without ' it makes no sense
// ^ But it STARTS A TEXT LITERAL
+ "p.csa_score,p.party_tn,p.rec_create_date,"
+ "s.strike_id, s.strike_date, s.strike_level, s.strike_status, s.appealable,s.appeal_status,s.rec_change_date,s.event_id,s.is_email_processed,s.policy_id"
+ "FROM strike s "
// ^ Missing space, but it's in a text literal so doesn't matter
+ "INNER JOIN parties p"
+ "ON p.party_id = s.party_id"
// ^ Missing space, but it's in a text literal so doesn't matter
+ "WHERE p.account ='"+appealStatus.getSubscriberId()
// ^ Missing space, but it's in a text literal so doesn't matter
// ^ END TEXT LITERAL from first line
// ^ error complains about inserted value 0957936101205
+"'AND strike_status = '"+OCIRISConstants.STRIKE_STATUS_ACTIVE+"' ");)
// ^ Starts a new text literal
// ^ Missing space, but it's in a text literal so doesn't matter
// ^ end text literal
// ^ would complain about inserted value ACTIVE
// ^ Dangling '
Also, you shouldn't be using string concatenation to build the SQL, since it'll cause syntax errors and leave you susceptible to SQL Injection attacks, allowing hackers to steal your data and delete your tables.
Assuming the initial SELECT MAX( ... WHERE ' is in error, here is a cleaned up version, formatted for clarity:
String sql = "SELECT p.party_type_id, p.csa_score, p.party_tn, p.rec_create_date" +
", s.strike_id, s.strike_date, s.strike_level, s.strike_status" +
", s.appealable, s.appeal_status, s.rec_change_date, s.event_id" +
", s.is_email_processed, s.policy_id" +
" FROM strike s" +
" INNER JOIN parties p ON p.party_id = s.party_id" +
" WHERE p.account = ?" +
" AND strike_status = ?";
try (Connection conn = DBConnectionManager.getIntakeConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, appealStatus.getSubscriberId());
stmt.setString(2, OCIRISConstants.STRIKE_STATUS_ACTIVE);
The specific syntax error there is saying that there should be a space before the AND on the last line of the query:
+"' AND strike_status // ... etc
^ Insert a space here
However, you have several other problems there, e.g. you have not got spaces around line breaks, e.g.
+ "INNER JOIN parties p"
+ "ON p.party_id = s.party_id"
would become
+ "INNER JOIN parties pON p.party_id = s.party_id"
You should insert more spaces appropriately, either at the start or end of each line.
There are other syntax errors like WHERE 'SELECT. You need to check all of your syntax very carefully.
Also: concatenating values into prepared statements somewhat defeats the point of prepared statements. See the Javadoc for examples of how to use them correctly.
I don`t get it. I created a query where made some joins of two tables in SQLite. In my SQLite Browser there is all ok and the columns are displayed correctly. But when I call executeQuery, I always get the error:
[SQLITE_ERROR] SQL error or missing database (no such column: td.value)
Here is my statement:
private static final String QUERY_ENDUSES = "SELECT td.Value Value, reportn.Value ReportName, fs.Value ReportForString, tn.Value TableName, rn.Value RowName, cn.Value ColumnName, u.Value Units, RowId "
+ "FROM TabularData td"
+ "INNER JOIN Strings reportn ON reportn.StringIndex=td.ReportNameIndex "
+ "INNER JOIN Strings fs ON fs.StringIndex=td.ReportForStringIndex "
+ "INNER JOIN Strings tn ON tn.StringIndex=td.TableNameIndex "
+ "INNER JOIN Strings rn ON rn.StringIndex=td.RowNameIndex "
+ "INNER JOIN Strings cn ON cn.StringIndex=td.ColumnNameIndex "
+ "INNER JOIN Strings u ON u.StringIndex=td.UnitsIndex WHERE report n.StringTypeIndex=1 AND fs.StringTypeIndex=2 AND tn.StringTypeIndex=3 AND rn.StringTypeIndex=4 AND cn.StringTypeIndex=5 AND u.StringTypeIndex=6 "
+ "AND td.ReportNameIndex = 1 AND tn.StringIndex = 59;";
If I substitute the statement through Select td.value from TabularData td , then all is OK!
Can anybody help me?
You're missing a space between td in the FROM clause, and the first INNER.
String sql = "INSERT INTO order " + "(customerid, pant, shirt, date) "
+ "VALUES ('" + jTextField1.getText() + "','" + jTextField2.getText()
+ "','" + jTextField3.getText() + "','" + jTextField4.getText() + "')";
When tried this, I got the following error:
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
'order (customerid, pant, shirt, date) VALUES ('10','2','3','26')' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method).
You need to escape reserved words like order with backticks
INSERT INTO `order` (customerid, ...
Besides that I recommend using Prepared Statements.
Table name "order" is reserve word so please change table name and try it.
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.