SQL statement works in Workbench but not in Java - java

The SQL statement below works in mySQL Workbench, but when I execute it in Eclipse, there is an mySQL exeception 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 'by schedule.id' at line 1
String sqlStr = "select movie_db.movie , schedule.date , schedule.timeslot "
+ ", schedule.seats as NoSeats,"
+ " a.bookingsMade, if ( (schedule.seats-a.bookingsMade) is null, schedule.seats,(schedule.seats-a.bookingsMade) ) as availSeats"
+ " ,schedule.movie_id, schedule.id as scID"
+ " from schedule"
+ " left outer join movie_db on ( movie_db.id=schedule.movie_id )"
+ " left outer join ("
+ " select count(*) as bookingsMade, tickets.movie_id as aid from tickets"
+ " group by schedule_id"
+ " ) as a on (schedule.id=a.aid)"
+ " where schedule.movie_id=?"
+ "group by schedule.id";
PreparedStatement pstmt = sqlConnect.getPreparedStatement(sqlStr);
pstmt.setInt(1, Integer.parseInt(movieId));
ResultSet rs = pstmt.executeQuery();

that cannot work:
where schedule.movie_id=?"
+ "group by schedule.id";
change it to
where schedule.movie_id=?"
+ " group by schedule.id";

Related

Got an exception! You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax

I got this error i am using java and javafx and it is connected to MYsql DB i got this error while excute this statment from java to my sql please help
Got an exception!
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 'update kstds.match SET
kstds.match.Team1Goals=kstds.match.Team1Goals+1 where kst' at line 1
String Query ="use kstds; update kstds.match SET kstds.match.Team1Goals=kstds.match.Team1Goals+1 "
+ "where kstds.match.Team1ID= ( select kstds.team.TeamID from kstds.team where kstds.team.Name='AHLI' ) "
+ "and kstds.match.Matchid = 1 ; "
+ "Update kstds.match SET kstds.match.Team2Goals=kstds.match.Team2Goals+1 "
+ "where kstds.match.Team2ID= ( select kstds.team.TeamID from kstds.team where kstds.team.Name='AHLI' ) "
+ "and kstds.match.Matchid=1;";
you are trying to execute multiple sql queries which should be done using addBatch & executeBatch.
you don't have to execute use kstds because the connection to the database is set via Java
try this:
String Query1 ="update match SET match.Team1Goals=match.Team1Goals+1 "
+ "where match.Team1ID= ( select team.TeamID from team where team.Name='AHLI' ) "
+ "and match.Matchid = 1 ; "
String Query2 ="Update match SET match.Team2Goals=match.Team2Goals+1 "
+ "where match.Team2ID= ( select team.TeamID from team where team.Name='AHLI' ) "
+ "and match.Matchid=1;";
//stmt is your Statement and conn is your Connection
con.setAutoCommit(false);
stmt.addBatch(Query1);
stmt.addBatch(Query2);
stmt.executeBatch();
con.commit();

Stacktrace with SQL injection?

If i insert a quote symbol " in the codContract parameter I receive the following error.
Error querying database. Cause: java.sql.SQLSyntaxErrorException:
ORA-00972: identifier too long
The error may exist in mappers/existence.xml The error may involve
com.iv.queryinterface.AssistenzaMapper.getTitlesFromCodContratct-Inline
The error occurred while setting parameters
SQL:
SELECT t.id_title,
c.des_lastname,
c.des_firstname,
to_char(t.dta_raw, 'DD/MM/YYYY') AS DTA_RAW,
DECODE(t.cod_statustitle, '1', 'Raw', '2', 'Stated') AS STATUS_TITLE
FROM Ivf_Policy p,
Ivf_Title t,
Ivg_Client c,
Ivf_Price pr
WHERE Cod_Contract = TEST
AND p.id_policy = t.id_policy
AND t.cod_type_title IN(2, 3, 13)
AND t.cod_statustitle IN(1, 2)
AND t.cod_client = c.cod_client
AND t.id_price = pr.id_price;
Cause: java.sql.SQLSyntaxErrorException: ORA-00972: identifier too
long
In this example, i set " TEST as value for the codContract parameter. My questions are:
Is this an exploitable SQL injection or a false positive that just prints an sql error into the stack trace?
The code is susceptible to SQL injection, and does no escaping. All that is avoidable by the use of PreparedStatement. Where the query string is not composed dynamically.
Now "TEST is the first part of an SQL identifier till a closing double quote.
I do not want to instruct readers on hacking, but think what something like
"'' OR 1=1 "
+ "UNION SELECT u.login, u.password, '', '', '', '' "
+ "FROM users"
+ "\u0000-- ";
might reveal on data.
Use java.sql.PreparedStatement for avoiding SQL injection.
String query =
"SELECT " +
" t.id_title , " +
" c.des_lastname , " +
" c.des_firstname , " +
" TO_CHAR(t.dta_raw, 'DD/MM/YYYY') AS DTA_RAW, " +
" DECODE(t.cod_statustitle, '1', 'Raw', '2', 'Stated') AS STATUS_TITLE " +
"FROM " +
" Ivf_Policy p, " +
" Ivf_Title t, " +
" Ivg_Client c, " +
" Ivf_Price pr " +
"WHERE " +
"1 = 1 AND " +
" Cod_Contract = ? " +
"AND p.id_policy = t.id_policy " +
"AND t.cod_type_title IN(2, " +
" 3, " +
" 13) " +
"AND t.cod_statustitle IN(1, " +
" 2) " +
"AND t.cod_client = c.cod_client " +
"AND t.id_price = pr.id_price;";
PreparedStatement stmt = connection.prepareStatement(query);
stmt.setString(1, 'TEST');
ResultSet rs = stmt.executeQuery();
To avoid SQL injection, do not append parameter values directly to SQL queries.
Use bind variables instead.
Thanks.

SQL Statement not working on Oracle JDBC

I have a statement that could retrieve last month's transaction records from Oracle:
select
c.CustomerID as id,
c.Order_ID as txID,
c.Transaction_Date as date1
from
Members a, Verify_Detail b, Verify_Request c
where
a.CustomerID = b.CustomerID AND
b.CustomerID = c.CustomerID AND
b.Order_ID = c.Order_ID AND
c.Transaction_Date between add_months(trunc(sysdate,'mm'),-1) and last_day(add_months(trunc(sysdate,'mm'),-1))
order by
c.CustomerID, c.Transaction_Date desc
This statement works fine on SQL Developer. But when I use JDBC and Prepared statement to try to fetch my data, it shows me exception 17006: Invalid Column Name, Cause: null all the time.
I'd like to know what is wrong with my statement that made me unable to execute it on JDBC? Isn't it support to be executed if I could use it on Oracle SQL Developer?
Update:
The code that I use is simple:
try {
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("jdbc/myDBSrc");
Connection con = ds.getConnection();
String sql = "select " +
"c.CustomerID as id, c.Order_ID as txID, c.Transaction_Date as date1 " +
"from Members a, Verify_Detail b, Verify_Request c " +
"where a.CustomerID = b.CustomerID AND b.CustomerID = c.CustomerID AND " +
"b.Order_ID = c.Order_ID AND " +
"c.Transaction_Date between add_months(trunc(sysdate,'mm'),-1) and last_day(add_months(trunc(sysdate,'mm'),-1)) " +
"order by c.CustomerID, c.Transaction_Date desc";
PreparedStatement pstmt = con.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
while(rs.next()){
out.println("ID: " + rs.getLong("id") + ", txID: " + rs.getString("txID") + ", Date: " + rs.getString("date1"));
}
}
catch(SQLException e){
out.println("SQL state: " + e.getSQLState() + ", Code: " + e.getErrorCode() + ", Msg: " + e.getMessage() + ", Cause: " + e.getCause());
}
This is only a guess, but too large for the comments section...
Maybe you connected the lines in a way that two consecutive lines get merged (in my example, the AND from one line merges with b.CustomerID from the next):
PreparedStatement stmt = conn.prepareStatement("select "+
"c.CustomerID as id, "+
"c.Order_ID as txID, "+
"c.Transaction_Date as date1 "+
"from "+
"Members a, Verify_Detail b, Verify_Request c "+
"where "+
"a.CustomerID = b.CustomerID AND" // <=====
"b.CustomerID = c.CustomerID AND "+
"b.Order_ID = c.Order_ID AND "+
"c.Transaction_Date between add_months(trunc(sysdate,'mm'),-1) "+
"and last_day(add_months(trunc(sysdate,'mm'),-1)) "+
"order by "+
"c.CustomerID, c.Transaction_Date desc");
EDIT: I think the reason is much simpler... it's Oracle turning all Identifiers to uppercase, so try this:
String sql = "select " +
"c.CustomerID as \"id\", c.Order_ID as \"txID\", c.Transaction_Date as \"date1\" " +
"from Members a, Verify_Detail b, Verify_Request c " +
"where a.CustomerID = b.CustomerID AND b.CustomerID = c.CustomerID AND " +
"b.Order_ID = c.Order_ID AND " +
"c.Transaction_Date between add_months(trunc(sysdate,'mm'),-1) and last_day(add_months(trunc(sysdate,'mm'),-1)) " +
"order by c.CustomerID, c.Transaction_Date desc";
17006: Invalid Column Name Is raised if you are trying to get not existing column from result set.
1) Option Add external select and try again select * from (your_select)
2) Try to get data with column names.
"ID: " + rs.getLong("CustomerID") + ", txID: " + rs.getString("Order_ID") + ", Date: " + rs.getString("Transaction_Date")
I know there is connection propertie GET_COLUMN_LABEL_FOR_NAME. And if is set to false. ResultSet only knows real column_name. But i'm not sure if ojdbc supports it.

SQL Query deleting duplicate records not working

Good day. I have a query in my Java code that deletes duplicate rows in a table. Initially it worked and for a while i didn't touch the project. But on running the file a few days ago, my code was throwing exceptions. This is my code:
String query = "DELETE error_log FROM error_log INNER JOIN "
+ "(SELECT min(id) minid, service_source, channel,transaction_type, provider_name, pido_account, beneficiary_id, error_description, error_date FROM error_log "
+ "GROUP BY service_source, channel, transaction_type, provider_name, pido_account, beneficiary_id, error_description, error_date "
+ "HAVING COUNT(1) > 1 AS duplicates ON "
+ "(duplicates.service_source = error_log.service_source AND duplicates.channel = error_log.channel "
+ "AND duplicates.transaction_type = error_log.transaction_type AND duplicates.provider_name = error_log.provider_name "
+ "AND duplicates.pido_account = error_log.pido_account AND duplicates.beneficiary_id = error_log.beneficiary_id "
+ "AND duplicates.error_description = error_log.error_description AND duplicates.error_date = error_log.error_date "
+ "AND duplicates.minid <> error_log.id"
+ ")"
+ ")";
int deploy = duplicate.executeUpdate(query);
I get this afterwards:
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 'AS duplicates ON (duplicates.service_source = error_log.service_source AND dupli' at line 1.
How do i correct this and have the duplicates deleted from the table?
You have a missing ) on line + "HAVING COUNT(1) > 1 AS duplicates ON " and have an extra ) at the end.
String query = "DELETE error_log FROM error_log INNER JOIN "
+ "(SELECT min(id) minid, service_source, channel,transaction_type, provider_name, pido_account, beneficiary_id, error_description, error_date FROM error_log "
+ "GROUP BY service_source, channel, transaction_type, provider_name, pido_account, beneficiary_id, error_description, error_date "
+ "HAVING COUNT(1) > 1 ) AS duplicates ON "
+ "(duplicates.service_source = error_log.service_source AND duplicates.channel = error_log.channel "
+ "AND duplicates.transaction_type = error_log.transaction_type AND duplicates.provider_name = error_log.provider_name "
+ "AND duplicates.pido_account = error_log.pido_account AND duplicates.beneficiary_id = error_log.beneficiary_id "
+ "AND duplicates.error_description = error_log.error_description AND duplicates.error_date = error_log.error_date "
+ "AND duplicates.minid <> error_log.id"
+ ")";
int deploy = duplicate.executeUpdate(query);
If you haven't made any changes and it stopped working, 1) are you sure you tested this code? and 2) has anyone else made any changes without your knowledge?

SQL Query Will Not Execute SQLite, Java

Problem Synopsis:
When attempting to execute a SQL query in Java with a SQLite Database, the SQL statement fails to return from the execute() or executeQuery() method. In other words, the system "hangs" when executing this SQL statement.
Question:
What am I doing wrong to explain why the ResultSet never "returns?"
TroubleShooting
I tried to narrow the problem and the problem seems to be with the Java execute() or executeQuery(). A ResultSet never seems to return. For example, I tried executing exactly the same query directly in SQLite (that is, using a SQLite DB manager). The query (outside Java) executes in about 5ms and returns the valid result set.
NOTE: No exception is thrown. The system merely seems to "hang" and becomes unresponsive until a manual kill. (waiting more than 10 minutes.)
Code:
I heavily edited this code to make the problem simpler to see. (In production, this uses Prepared Statements. But, the error occurs in both methods--straight Statement and prepared Statement versions.)
Basically, the SELECT returns a single DB item so the user can review that item.
Statement st = conn.createStatement() ;
ResultSet rs = st.executeQuery("SELECT DISTINCT d1.id, d1.sourcefullfilepath, " +
"d1.sourcefilepath, d1.sourcefilename, d1.classificationid, d1.classid, " +
"d1.userid FROM MatterDataset, (SELECT MatterDataset.id, " +
"MatterDataset.sourcefullfilepath, MatterDataset.sourcefilepath, " +
"MatterDataset.sourcefilename, MatterDataset.matterid , " +
"DocumentClassification.classificationid, DocumentClassification.classid," +
" DocumentClassification.userid FROM MatterDataset " +
"LEFT JOIN DocumentClassification ON " +
"DocumentClassification.documentid = Matterdataset.id " +
"WHERE ( DocumentClassification.classid = 1 OR " +
"DocumentClassification.classid = 2 ) AND " +
"DocumentClassification.userid < 0 AND " +
"MatterDataset.matterid = \'100\' ) AS d1 " +
"LEFT JOIN PrivilegeLog ON " +
"d1.id = PrivilegeLog.documentparentid AND " +
"d1.matterid = PrivilegeLog.matterid " +
"WHERE PrivilegeLog.privilegelogitemid IS NULL " +
"AND MatterDataset.matterid = \'100\' " +
"ORDER BY d1.id LIMIT 1 ;") ;
Configuration:
Java 6,
JDBC Driver = Xerial sqlite-jdbc-3.7.2,
SQLite 3,
Windows
Update
Minor revision: as I continue to work with this, adding a MIN(d1.id) to the beginning of the SQL statement at least returns a ResultSet (rather than "hanging"). But, this is not really what I wanted as the MIN obviates the LIMIT function.
Statement st = conn.createStatement() ;
ResultSet rs = st.executeQuery("SELECT DISTINCT MIN(d1.id), d1.id,
d1.sourcefullfilepath, " +
"d1.sourcefilepath, d1.sourcefilename, d1.classificationid, d1.classid, " +
"d1.userid FROM MatterDataset, (SELECT MatterDataset.id, " +
"MatterDataset.sourcefullfilepath, MatterDataset.sourcefilepath, " +
"MatterDataset.sourcefilename, MatterDataset.matterid , " +
"DocumentClassification.classificationid, DocumentClassification.classid," +
" DocumentClassification.userid FROM MatterDataset " +
"LEFT JOIN DocumentClassification ON " +
"DocumentClassification.documentid = Matterdataset.id " +
"WHERE ( DocumentClassification.classid = 1 OR " +
"DocumentClassification.classid = 2 ) AND " +
"DocumentClassification.userid < 0 AND " +
"MatterDataset.matterid = \'100\' ) AS d1 " +
"LEFT JOIN PrivilegeLog ON " +
"d1.id = PrivilegeLog.documentparentid AND " +
"d1.matterid = PrivilegeLog.matterid " +
"WHERE PrivilegeLog.privilegelogitemid IS NULL " +
"AND MatterDataset.matterid = \'100\' " +
"ORDER BY d1.id LIMIT 1 ;") ;
What a messy SQL statement (sorry)! I don't know SQLite, but why not simplify to:
SELECT DISTINCT md.id, md.sourcefullfilepath, md.sourcefilepath, md.sourcefilename,
dc.classificationid, dc.classid, dc.userid
FROM MatterDataset md
LEFT JOIN DocumentClassification dc
ON dc.documentid = md.id
AND (dc.classid = 1 OR dc.classid = 2 )
AND dc.userid < 0
LEFT JOIN PrivilegeLog pl
ON md.id = pl.documentparentid
AND md.matterid = pl.matterid
WHERE pl.privilegelogitemid IS NULL
AND md.matterid = \'100\'
ORDER BY md.id LIMIT 1 ;
I was uncertain whether you wanted to LEFT JOIN or INNER JOIN to DocumentClassification (using LEFT JOIN and then put requirements on classid and userid in the WHERE statement is - in my opinion - contradictory). If DocumentClassification has to exist, then change to INNER JOIN and put the references to classid and userid into the WHERE clause, if DocumentClassification may or may not exist in your result set, then keep the query as I suggested above.
I went back and started over. The SQL syntax, while it worked outside Java, simply seemed too complex for the JDBC driver. This cleaned-up revision seems to work:
SELECT DISTINCT
MatterDataset.id, MatterDataset.sourcefullfilepath, MatterDataset.sourcefilepath,
MatterDataset.sourcefilename
FROM MatterDataset , DocumentClassification
ON DocumentClassification.documentid = MatterDataset.id
AND MatterDataset.matterid = DocumentClassification.matterid
LEFT JOIN PrivilegeLog ON MatterDataset.id = PrivilegeLog.documentparentid
AND MatterDataset.matterid = PrivilegeLog.matterid
WHERE PrivilegeLog.privilegelogitemid IS NULL
AND MatterDataset.matterid = '100'
AND (DocumentClassification.classid = 1 OR DocumentClassification.classid = 2)
AND DocumentClassification.userid = -99
ORDER BY MatterDataset.id LIMIT 1;
A nice lesson in: just because you can in SQL doesn't mean you should.
What this statement does is essentially locates items in the MatterDataset Table that are NOT in the PrivilegeLog table. The LEFT JOIN and IS NULL syntax locate the items that are "missing." That is, i want to find items that are in MatterDataset but not yet in PrivilegeLog and return those items.

Categories