SQL parameter issue Jdbc - java

I am taking input from user and storing in two different variables. I am binding the parameters with my sql statement. When i run the code its giving issue on concatenating part of query.
String CityA= null;
String CityB= null;
try {
CityA = readEntry(in, "Enter Origin City : ");
CityB = readEntry(in, "Enter Destination City : ");
// We treat this drop table specially to allow it to fail
// as it will the very first time we run this program
try {
String q = "SELECT f.FLNO,f.DISTANCE,TIMEDIFF(f.arrives,f.departs)
as Duration FROM FLIGHTS F"
+ " WHERE F.ORIGIN = "+CityA;
+ "AND f.DESTINATION = "+CityB;
System.out.println(q);
rset = stmt.executeQuery(q);
while (rset.next()) {
System.out.println(rset.getInt("FLNO") + ","
+ rset.getInt("Distance") + ","
+ rset.getTime("Duration"));
}
System.out.println("Done");
}
catch (SQLException e) {
// assume not there yet, so OK to continue
}
finally {
stmt.close();
}

Please find the code for query:-
Basically you missed the space between the CityA and AND
String q = "SELECT f.FLNO,f.DISTANCE,TIMEDIFF(f.arrives,f.departs) as Duration FROM FLIGHTS F"
+ " WHERE F.ORIGIN = '"+CityA+"' ";
+ "AND f.DESTINATION = '"+CityB+"'";

There is a typo in your query string - you missed the space between 'Los-Angeles' and AND.

Related

How to check if there is a specific number in the database

This is my entire code:
import java.sql.*;
import java.io.*;
public class VerInformacaoPassageiro {
public static void main(String args[]) {
String dbname = "BD22";
String dbuser = "postgres";
String password = "12345";
String url = "jdbc:postgresql://localhost:5432/" + dbname;
try {
BufferedReader in;
in = new BufferedReader( new InputStreamReader( System.in ));
System.out.print("Numero de identificacao: ");
String identificacao = in.readLine();
Connection c = DriverManager.getConnection(url, dbuser, password);
c.setAutoCommit(false);
Statement stmt = c.createStatement();
String query = "SELECT nomeP, sexo, destinopretendido, dataviagem " +
"FROM passageiros " +
"WHERE nidentificacao='" + identificacao + "';";
System.out.println("QUERY: " + query);
ResultSet rs = stmt.executeQuery(query);
System.out.println( "Informacao do passageiro com numero de identificacao " + identificacao);
System.out.println( "---------------------------------------");
while ( rs.next() ) {
int nidentificacaoP = rs.getInt("nidentificacao");
String nome = rs.getString("nomeP");
String sexo = rs.getString("sexo");
String destinopretendido = rs.getString("destinopretendido");
String dataviagem = rs.getString("dataviagem");
if (nidentificacaoP == NULL)
System.out.print("Identificacao nao encontrada");
else
System.out.println( nome + " do sexo " + sexo + " para o destino " + destinopretendido + " no dia " + dataviagem );
}
rs.close();
stmt.close();
c.close();
}
catch (Exception e) {
System.err.println( e.getClass().getName()+": "+ e.getMessage() );
System.exit(0);
}
}
}
But my doubt is in this part of the code:
if (nidentificacaoP == NULL)
System.out.print("Identificacao nao encontrada");
else
System.out.println( nome + " do sexo " + sexo + " para o destino " + destinopretendido + " no dia " + dataviagem );
}
rs.close();
stmt.close();
c.close();
My goal is to find a certain ID number in a database that will give me a passenger's information. If this ID is not in the database I want to use an if to write "ID not found" but I don't know how to do this. (I left it as NULL inside the if because I didn't know what to put in it so it won't be empty, so I can submit it here on Stack Overflow). What should I write inside the if to check if the ID exists?
There are at least 3 errors/misconceptions in this code.
SQL injection
String query = "SELECT nomeP, sexo, destinopretendido, dataviagem " +
"FROM passageiros " +
"WHERE nidentificacao='" + identificacao + "';";
Imagine the user types this on the command line:
Whatever' OR 1 == 1; EXEC 'FORMAT C: /Y'; --
That would mean the query matches many records (OR 1 == 1 means it matches all of them), and it'll format your drive. This is called SQL injection; to avoid it, use PreparedStatement and NEVER put user input directly into the SQL. In general your SQL statements should be string literals.
Selecting columns vs retrieving them
String query = "SELECT nomeP, sexo, destinopretendido, dataviagem " +
....
rs.getInt("nidentificacao")
Your select statement states that you want 4 values to be returned for each matching row in the query. You then ask for the value of row 'nidentificacao' which isn't in there. The only 4 string values valid in rs.getInt, are nomeP, sexo, destinopretendido and dataviagem, because those are the only 4 columns in the query.
Misunderstanding of how 'not found' is registered
Your query returns a number of rows. while (rs.next()) loops once for each row. If nidentificacao is unique, given that you are looking for a specific value of it, your query returns either 1 row, or 0 rows.
If no row with nidentificacao at the searched-for value exists, you would get no rows. In your code, you assume you get a row, with null as value for rs.getInt("nidentificacao"); which isn't how it works.
NULL misconception
In SQL, NULL is a thing. In java, there's, at best, null (case sensitive). The various .getX() methods tend to return a placeholder value and not null for SQL NULL values. For example, if your SQL query returns NULL and you call rs.getInt(column) to retrieve it, you get 0, not null - that's because in java primitives cannot be null.
It isn't relevant here (checking for SQL NULL is not how you determine that no results are found; you determine that by realizing rs.next() will return false always - even the first time you call it) - but if it had been, that's not how its done.
Assuming identificacao is a unique identifier, the query will return either one or no rows, so you don't need to process the result set with a while, but with an if:
// Single row found
if (rs.next()) {
int nidentificacaoP = rs.getInt("nidentificacao");
String nome = rs.getString("nomeP");
String sexo = rs.getString("sexo");
String destinopretendido = rs.getString("destinopretendido");
String dataviagem = rs.getString("dataviagem");
System.out.println
(nome + " do sexo " + sexo + " para o destino " +
destinopretendido + " no dia " + dataviagem);
// No row found
} else {
System.out.print("Identificacao nao encontrada");
}
Mandatory side note:
Concatenating the condition like that is at best a bad practice and at worst leaves your application vulnerable to SQL Injection attacks if identificacao is received from user-controlled input. You should probably convert this query to a PreparedStatemet with placeholders.

How make complex request in jdbc? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed last year.
Improve this question
I want to get random name from database.
#Override
public String createName() {
String result = "empty";
String sqlSelect;
sqlSelect = "select * from names";
String sqlOrderBy = "ORDER BY RAND()";
String sqlLimit = "Limit 1";
try {
statement = connection.createStatement();
resultSet = statement.executeQuery(sqlSelect + " ; " + sqlOrderBy + " + " + sqlLimit);
//resultSet.getString("name");
System.out.println("Random name from database: " + resultSet.getString("name"));
result = resultSet.getString("name");
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
I don't know how to create request rightly. I'm a beginner in jdbc
The error in your question is the String you pass to executeQuery.
It actually translates to this select * from names ; ORDER BY RAND() + Limit 1
But it should look like this select * from names ORDER BY RAND() LIMIT 1;
So adapt this row
resultSet = statement.executeQuery(sqlSelect + " ; " + sqlOrderBy + " + " + sqlLimit);
to:
resultSet = statement.executeQuery(sqlSelect + " " + sqlOrderBy + " " + sqlLimit+";");
Additionally, you should close all resources or swap to a try with resources block
Edit: there are still a few things wrong or should be optimized
#Override
public String createName() {
String result = "empty";
String sqlSelect;
sqlSelect = "select * from names";
String sqlOrderBy = "ORDER BY RAND()";
String sqlLimit = "Limit 1";
try (
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sqlSelect + " " + sqlOrderBy + " " + sqlLimit+";"))
{
while(restultSet.next(){
result = resultSet.getString("name");
System.out.println("Random name from database: " + result);
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
I switched to try with resources, so you do not have to worry about closing them since they implement the AutoClosable Interface.
Additionally you didn't mention ResultSet and Statement as variable type which makes me think that you declared it somewhere at class level. That would be a bad idea.
Edit2:
You should also use the while(ResultSet.next()) this moves the "cursor" forward and you can access the first element. If your resultset would return more rows, then it iterates over all rows and you can deal with the data in that block.

ORA-00923: FROM keyword not found where expected in SeleniumWebDriver

I created a class (ValidarStatusOsPage) in java that makes a connection to the DB and returns to a test class (ValidateStatusOsTest) the result of the query and prints to the screen.
When I run the test class, the Eclipse console displays the message:
ORA-00923: FROM keyword not found where expecte
I have reviewed the code several times but I can not verify where the error is.
Below is the Java class for connecting to the DB and the test class.
public class ValidarStatusOsTest {
static String query;
#Test
public void validarOs() {
ValidarStatusOsPage os = new ValidarStatusOsPage();
query = os.returnDb("179195454");
}}
public class ValidarStatusOsPage {
String resultado;
public String returnDb(String NuOs) {
// Connection URL Syntax: "jdbc:mysql://ipaddress:portnumber/db_name"
String dbUrl = "jdbc:oracle:thin:#10.5.12.116:1521:desenv01";
// Database Username
String username = "bkofficeadm";
// Database Password
String password = "bkofficeadmdesenv01";
// Query to Execute
String query = "SELECT NU_OS, CD_ESTRATEGIA, CD_STATUS, NU_MATR, DT_ABERTURA" +
"FROM tb_bkoffice_os"+
"WHERE NU_OS ="+ NuOs +"";
try {
// Load mysql jdbc driver
Class.forName("oracle.jdbc.driver.OracleDriver");
// Create Connection to DB
Connection con = DriverManager.getConnection(dbUrl, username, password);
// Create Statement Object
Statement stmt = con.createStatement();
// Execute the SQL Query. Store results in ResultSet
ResultSet rs = stmt.executeQuery(query);
// While Loop to iterate through all data and print results
while (rs.next()) {
String NU_OS = rs.getString(1);
String CD_ESTRATEGIA = rs.getString(2);
String CD_STATUS = rs.getString(3);
String NU_MATR = rs.getString(4);
String DT_ABERTURA = rs.getString(5);
resultado = NU_OS + " " + CD_ESTRATEGIA + " " + CD_STATUS + " " + NU_MATR + " " + DT_ABERTURA + "\n";
System.out.println(NU_OS + " - " + CD_ESTRATEGIA + " - " + CD_STATUS + " - " + NU_MATR + " - "+ DT_ABERTURA);
}
// closing DB Connection
con.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return resultado;
}}
3 points are there in your query:
SELECT NU_OS, CD_ESTRATEGIA, CD_STATUS, NU_MATR, DT_ABERTURA" +
"FROM tb_bkoffice_os"+
"WHERE NU_OS ="+ NuOs +""
space before FROM missed first part of query is: SELECT NU_OS, CD_ESTRATEGIA, CD_STATUS, NU_MATR, DT_ABERTURAFROM
space missed before WHERE: SELECT NU_OS, CD_ESTRATEGIA, CD_STATUS, NU_MATR, DT_ABERTURAFROM tb_bkoffice_osWHERE NU_OS =
concatenate parameter into SQL string is exact hack point for SQL Injection attack. Never do it in real program even if it is pure standalone. Always use parameters for queries.
and a little last one: + NuOs +"" - last "" has no sense at all...
good luck.
UPD: #YCF_L absolutely right use Prepared statement.
you need to do this:
in Sql String: WHERE NU_OS = ?
in code:
PreparedStatement stmt = con.prepareStatement(query);
stmt.setString(1, NuOs);
//also works: stmt.setObject(1,NuOs);
things to remember with JDBC:
all parameters in SQL are just ? marks
parameter indexes start with 1 (not 0)
and in order they appear in SQL from strat to end
(e.g. Select * FROM tbl WHERE col1=? and col2=?
has parameter 1 for col1 and parameter 2 for col2
PS. your initial SQL has one more error but I'm not going to tell you what is it :-) use parameter and all be fine.

Error: Incorrect syntax near (database name)

hi I am getting this error in my Java program. Here is my query. It is working good in SQL server. but getting
Error: Incorrect syntax near 'WebApp'.
private static final String SERVICES =
"SELECT s.Service_ID "
+ ",s.[Location_ID] "
+ ",COALESCE(st.[Service_Type_Name],s.[Service_Name]) AS Service_name "
+ ",st.Service_Type_Name "
+ " FROM [WebApp].[dbo].[Services] s join [WebApp].[dbo].[ServiceTypes] st on s.Service_Type=st.Service_Type_ID "
+ " join WebApp.dbo.Locations l on s.Location_ID=l.Location_ID "
+ " where s.Deleted=0 "
+ " ORDER BY Location_ID ";
and here is my method it is working fine on ms sql server 2008
public List<MAServiceVO> getAddServices() throws CoopCRSAPIException {
ArrayList<MAServiceVO> results = new ArrayList<MAServiceVO>();
MAServiceVO maServiceVO = null;
log.debug("==========IN VendorDAOimpl.java (service)===========");
//int serviceID = 0;
//int prevServiceID = 0;
try {
conn = MSSQLDAOFactory.createConnection();
stmt = conn.prepareStatement(SERVICES);
// stmt.setTimestamp(1, startDate);
// stmt.setTimestamp(2, endDate);
stmt.execute();
rs = stmt.getResultSet();
while (rs.next()) {
// create new service
maServiceVO = new MAServiceVO();
// set service fields
maServiceVO.setServiceID(rs.getInt("Service_ID"));
maServiceVO.setLocationID(rs.getInt("Location_ID"));
maServiceVO.setServiceName(rs.getString("Service_Name"));
maServiceVO.setServiceType(rs.getString("Service_Type_Name"));
log.debug("==========done with VendorDAOimpl.java (service)===========");
}
} catch (SQLException e) {
log.debug(e.getMessage());
throw new CoopCRSAPIException(e.getMessage(), " VendorDAOimpl", "getAddServices", 500);
} finally {
closeConnections("getAddServices");
}
log.debug("&&&&&&&&&&&&&&&&&&&&&");
log.debug("==========finsh===========");
return results;
}
I don't see anything out of whack there. If there a reason you don't have this in a stored procedure instead of pass through sql? I did notice you didn't put square brackets around your final join but that shouldn't make any difference.
Here is your query after stripping off all the extra string parts for java.
SELECT s.Service_ID
, s.[Location_ID]
, COALESCE(st.[Service_Type_Name], s.[Service_Name]) AS Service_name
, st.Service_Type_Name
FROM [WebApp].[dbo].[Services] s
join [WebApp].[dbo].[ServiceTypes] st on s.Service_Type = st.Service_Type_ID
join [WebApp].[dbo].[Locations] l on s.Location_ID = l.Location_ID
where s.Deleted = 0
ORDER BY Location_ID;

Data does not get inserted into the table sometime

I have a table A. I insert data into table A through a user interface. Table A has an ID(primary key), which is generated using a sequence, and 16 other columns. One of the column is called cntrct_no.
When I try to insert data into the table through UI, it works fine the first time. I check the table A and all the data are there.
But when I try to insert the same data again without changing anything, it looks like the data is getting added to the table and I do not get any errors. But when I check table A, the data inserted the second time is not there.
If I try to insert the same data directly thorough SQL developer, the data gets inserted into the table.
The weird thing is if I just change the value of the cntrct_no in the UI and leave rest of the data same, the data gets inserted.
Can anyone please explain to me what could possibly cause this?
Not sure if this helps: stmt.executeUpdate(); returns 0 when the data is not inserted and a 1 when it's inserted.
public void writeToAudit(String contractNo, String tripNo,
String tripEffDate,
String tripDiscDate, String transpModeId, String userId,
String transType, AplLeg[] legs) {
final Session session = HibernateUtil.getSession();
Connection con = null;
con = session.connection();
PreparedStatement stmt = null;
PreparedStatement stmtSelId = null;
ResultSet rs = null;
long nextId = -1;
int i=0;
try {
for(i=0;i<legs.length;i++) {
String sqlNextId = "SELECT rpt_audit_transportation_seq.NEXTVAL as seqval FROM DUAL";
stmtSelId = con.prepareStatement(sqlNextId, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
rs = stmtSelId.executeQuery();
rs.last();
final int rows = rs.getRow();
if (rows == 0){
nextId = -1;
}
rs.beforeFirst();
rs.next();
nextId = rs.getInt(1);
if(nextId==-1)
throw new SQLException("Cannot get next val from rpt_audit_transportation sequence.");
stmt = con.prepareStatement(WRITE_TO_AUDIT_DML);
stmt.setLong(1, nextId);
stmt.setString(2, userId.toUpperCase());
stmt.setString(3, transType);
stmt.setString(4, contractNo);
stmt.setString(5, tripNo);
stmt.setInt(6, Integer.parseInt(transpModeId));
stmt.setString(7, tripEffDate);
stmt.setString(8, tripDiscDate);
stmt.setLong(9, legs[i].getLegId().longValue());
int temp = stmt.executeUpdate();
con.commit();
}
stmt.close();
}
catch (Exception e) {
}
finally {
closeConnection(session, con, stmtSelId, rs);
}
}
THE SQL STATEMENT:
private static final String WRITE_TO_AUDIT_DML =
"INSERT INTO rpt_audit_transportation " +
"(audit_id, audit_date, audit_process, audit_userid, " +
"audit_trans_type, audit_route_no, audit_trip_no, " +
"audit_eff_dt, audit_disc_dt, audit_orig_facility_id, " +
"audit_dest_facility_id, audit_arvl_tm, audit_dprt_tm, " +
"audit_leg_seq_no, audit_freq_id, audit_trnsp_mode_id) " +
"(SELECT ?, " + // audit id
"SYSDATE, " +
"'TOPS_UI', " +
"?, " + // userId
"?, " +
"rte.cntrct_no, " +
"trp.trip_no, " +
"rte.cntrct_eff_dt, " +
"rte.cntrct_disc_dt, " +
"NVL(leg.orig_facility_id, trp.orig_fac_id), " +
"NVL(leg.dest_facility_id, trp.dest_fac_id), " +
"NVL(leg.arvl_tm, trp.arvl_tm), " +
"NVL(leg.dprt_tm, trp.dprt_tm), " +
"leg.leg_seq, " +
"trp.freq_id, " +
"rte.trnsp_mode_id " +
"FROM apl_contract rte, " +
"apl_trip trp, " +
"apl_leg leg " +
"WHERE rte.cntrct_no = ? " + // contract id
"AND trp.trip_no = ? " + // trip no
"AND rte.trnsp_mode_id = ? " + // transp mode id
"AND rte.cntrct_locked_ind = 'N' " +
"AND trp.trip_eff_dt = to_date(?,'MM/DD/YYYY') " + // trip eff date
"AND trp.trip_disc_dt = to_date(?,'MM/DD/YYYY') " + // trip disc date
"AND trp.cntrct_id = rte.cntrct_id " +
"AND leg.trip_id = trp.trip_id " +
"AND leg.leg_id = ?) ";
Looks like you're not inserting plain values, but a result of a select based on the parameters.
What you are using is an INSERT ... SELECT () clause, so if the SELECT part does not return any rows, the INSERT won't insert anything, and stmt.executeUpdate() will return 0. Find out why SELECT returns no rows.
This may be due some triggers saving stuff in other tables when you do the insert into rpt_audit_transportation, but it's just a guess.
The problem is that you have a catch that is swallowing your exceptions
catch (Exception e) {
}
That means that when the SQL statement throws an error, you're telling your code to catch the exception and ignore it. It is almost always an error to do that since, as you're discovering, it means that your code can fail to do what you expect with no way of letting you know that something failed. At a minimum, you would need to log the exception somewhere. In general, though, if you cannot fix whatever condition lead to the exception, you ought to re-raise the exception or simply not catch it in the first place.
My guess is that the second insert is violating some constraint defined on the table. But since your code is catching the exception and throwing it away, you're not being notified that there was a constraint violation nor is your code noting which constraint was violated.
When the cntrct_no is same you are getting an exception and you are supperessing that as told by #Justin Cave. This may be because you are having a unique constraint for that field and the DB throws an error and you are suppressing.
When cntrct_no is changed - obviously the constraint wont fail and for primary key since you are using the sequence it would have generated the next number and it happily gets inserted in the DB.
Don't ever suppress the exception. Do some thing in that block either rethrow as application specific exception or convert to error code and propagate that to the front end.

Categories