I've connected this program to my database, and everytime that I try to run it it shows me this error:
Selecione id da Encomenda:
3
java.sql.SQLSyntaxErrorException: Comparisons between 'INTEGER' and 'CHAR (UCS_BASIC)' are not supported. Types must be comparable. String types must also have matching collation. If collation does not match, a possible solution is to cast operands to force them to the default collation (e.g. SELECT tablename FROM sys.systables WHERE CAST(tablename AS VARCHAR(128)) = 'T1')
BUILD SUCCESSFUL (total time: 3 seconds)
My imports
import java.sql.*;
import java.io.*;
import java.math.BigDecimal;
import java.util.Scanner;
I have a few more queries just like that one but with VARCHAR and those work fine.
The Column ENCOMENDAS inside the table DETALHES_ENCOMENDA is a INTEGER type like a ID, I already tried a lot of things but not even one worked
Can you guys help me?
Thanks!
try {
BufferedReader in;
in = new BufferedReader( new InputStreamReader( System.in ));
System.out.print("\nConsultar lista de artigos de uma encomenda.\n");
System.out.print("\nSelecione id da Encomenda: \n");
String NR = in.readLine();
Connection c = DriverManager.getConnection("jdbc:derby://localhost:1527/loja_inf/","luis","admin");
c.setAutoCommit(false);
Statement stmt = c.createStatement();
String query = " SELECT QUANTIDADE, IDPRODUTO, TIPOPRODUTO, FABRICANTE, MODELO, PRECO " +
" FROM DETALHES_ENCOMENDA " +
" INNER JOIN PRODUTOS " +
" ON DETALHES_ENCOMENDA.PRODUTO = PRODUTOS.IDPRODUTO " +
" WHERE ENCOMENDA = '"+ NR +"' ";
ResultSet rs = stmt.executeQuery(query);
System.out.println( "Artigos da encomenda nº:" + NR);
System.out.println( "---------------------------------------");
while ( rs.next() ) {
String FABRICANTE = rs.getString("FABRICANTE");
String MODELO = rs.getString("MODELO");
String PRECO = rs.getString("PRECO");
String TIPOPRODUTO = rs.getString("TIPOPRODUTO");
int QUANTIDADE = rs.getInt("QUANTIDADE");
int IDPRODUTO = rs.getInt("IDPRODUTO");
if( rs.wasNull() )
System.out.println( "A Encomenda nº:" + NR + " não existe.");
else
System.out.println("Id Produto: " + IDPRODUTO + " Tipo de Produto " + TIPOPRODUTO + " Fabricante: " + FABRICANTE + " Modelo: " + MODELO + " Preço: " + PRECO + " Quantidade: " + QUANTIDADE );
}
rs.close();
stmt.close();
c.close();
}
catch (Exception e) {
System.err.println( e.getClass().getName()+": "+ e.getMessage() );
System.exit(0);
}
}
First, you have to verify that what you have in NR is a number and not a string that can't be used as a number.
int num = Integer.parseInt( NR );
You have a catch-all statement below, so if you get NumberFormatException in that statement, it will be caught by it. But of course, you can add an internal catch to handle the situation and ask the user for a new input, if you wish.
The next stage is not to use single quotes. Instead of:
" WHERE ENCOMENDA = '"+ NR +"' ";
You have to use
" WHERE ENCOMENDA = "+ num +" ";
Without the single quotes that tell the database system that this is the string '3' instead of the number 3. Use the num variable that contains the number you parsed earlier.
This should solve your problem. However, it is strongly recommended to use a prepared statement instead of trying to build queries directly from user inputs. Prepared statements protect you against all sorts of hacking attempts or plain user errors, and are also more efficient when you repeat the same query again and again.
Related
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.
count_teachers(dept_name VARCHAR): return as an OUT parameter the total number of teachers belonging to the department named exactly as dept_name.
I can't do this last part of the exercise, I need to do this procedure in Java. I don't know how to do this subquery because it is inside a procedure with in and out parameters
public static void count_Teacher_By_Department_Procedure() {
try {
Connection con = conexion("jdbc:hsqldb:.\\database\\db");
Statement stt;
stt = con.createStatement();
String sql = "DROP PROCEDURE count_Teacher_By_Department_Procedure IF EXISTS;";
stt.executeUpdate(sql);
sql = "CREATE PROCEDURE count_Teacher_By_Department_Procedure(IN id int, OUT nombre Varchar(20))"
+ "READS sql DATA "
+ "BEGIN ATOMIC "
+ "SET id = SELECT COUNT id FROM teachers WHERE dept_num IN (SELECT dept_num FROM departments WHERE name = nombre); " // pasar al set el parametro out
+ "END";
stt.executeUpdate(sql);
con.close();
} //
catch (SQLException ex) {
Logger.getLogger(Act3_4.class.getName()).log(Level.SEVERE, null, ex);
}
}
It seems you have some syntax error and your IN and OUT parameters are not correct.
sql = "CREATE PROCEDURE count_Teacher_By_Department_Procedure(OUT idcount int, IN nombre Varchar(20))"
+ "READS sql DATA "
+ "BEGIN ATOMIC "
+ "SET idcount = SELECT COUNT( id ) FROM teachers WHERE dept_num IN (SELECT dept_num FROM departments WHERE name = nombre); " // pasar al set el parametro out
+ "END";
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.
I want to use either last name or first name to filter result shown on JTable from the database such that when i type either Nikola or Tesla in the JTextfield, the row with either of the names is filtered.
I have stored name as one field in the database i.e 'Nikola Tesla' when i type Nikola, it is working right and when i type Tesla it shows no result.
I have one field for name that stores both names.
I don't want to have separate First_Name and Last_Name field.
Please suggest what i should add on my code shown below:
private void jTextFieldSearchKeyReleased(java.awt.event.KeyEvent evt) {
try {
String selected = (String) jComboBoxSelected.getSelectedItem();
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/"
+ "employee_certificate", "root", "");
String sql = "SELECT stuff.Emp_Id,stuff.Emp_Name, stuff.Department, "
+ "certificate.Cert_Code, certificate.Cert_Name,\n"
+ "certificate.Cert, certificate.Vendor, certificate.Date_Taken, "
+ "certificate.Expiry_Date FROM stuff LEFT JOIN certificate"
+ " ON stuff.Emp_Id=certificate.Emp_Id "
+ "WHERE " + selected + " LIKE ? ORDER BY stuff.Emp_Name\n";
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, jTextFieldSearch.getText() + "%");
ResultSet rs = pstmt.executeQuery();
jTable1.setModel(DbUtils.resultSetToTableModel(rs));
pstmt.close();
con.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
You need to add % before the jTextFieldSearch.getText() also. See below
pstmt.setString(1, "%" + jTextFieldSearch.getText() + "%");
The true solution is this, you should to use %% inside quots '%%', without quotes you get that error:
LIKE '%Name%'
so, with prepared statement we should to change Name with ? and the result is like that:
String sql = "SELECT stuff.Emp_Id,stuff.Emp_Name, stuff.Department, "
+ "certificate.Cert_Code, certificate.Cert_Name,\n"
+ "certificate.Cert, certificate.Vendor, certificate.Date_Taken, "
+ "certificate.Expiry_Date FROM stuff LEFT JOIN certificate"
+ " ON stuff.Emp_Id=certificate.Emp_Id "
+ "WHERE " + selected + " LIKE '%?%' ORDER BY stuff.Emp_Name\n";
i hope this can help you, good luck.
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.