Java derby sql integer query - java

Please take a look at my code snippet below. What I am trying to achieve is querying the database for any results equal to the user input. It is querying SDS_NUMBER column which is an integer column.
When I execute the query it returns the following exception:
java.sql.SQLSyntaxErrorException: Comparisons between 'INTEGER' and
'CHAR (UCS_BASIC)' are not supported. Types must be comparable.
String types must also have matching collation....etc.
I understand that it is saying I am trying to compare an integer to char but I have tried to cast from examples I found on the net but no luck. Also I tried parseInt and using that value in the search but I still can't get it to work. Please advise what I am doing wrong and excuse my newbies to all of this.
} else if (tmp == "sdsNumber") {
try {
Integer sdsNum = Integer.parseInt(val);
String sql = "SELECT SDS_NUMBER, PRODUCT_NAME, PROPER_SHIPPING_NAME FROM APP.MASTER WHERE SDS_NUMBER = '"+sdsNum+"'";
pst = conn.prepareStatement(sql);
pst.executeQuery();
jTable1.setModel(DbUtils.resultSetToTableModel(rs));
} catch (Exception e) {
e.printStackTrace(System.out);
JOptionPane.showMessageDialog(null, e);
}
Master table creation:
CREATE TABLE MASTER
(
id integer NOT NULL GENERATED ALWAYS AS (START WITH 1, INCREMENT BY 1)
, SDS_NUMBER integer UNIQUE
, PRODUCT_NAME varchar(100)
, PRODUCT_DESCRIPTION varchar(500)
, SDS_FILE_PATH varchar(50)
, USE_STATUS BOOLEAN
, DATA_UPDATED date
, PROPER_SHIPPING_NAME varchar(100)
, SIGNAL_WORD varchar(20)
, CONSTRAINT MASTER_PRIMARY_KEY PRIMARY KEY (id)
);

it seems you're wrapping an integer in quotes
SDS_NUMBER = '"+sdsNum+"'"
probably what you want is
SDS_NUMBER = ?
and then set the number with your PreparedStatement instead of concatenating strings
see http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
and
http://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html#setInt%28int,%20int%29

Remove the single quote "'"+sdsNum+"'" to be a number
Her ara Example by using preparedStatement
String sql = "SELECT SDS_NUMBER, PRODUCT_NAME, PROPER_SHIPPING_NAME FROM APP.MASTER WHERE SDS_NUMBER = ?";
pst = conn.prepareStatement(sql);
pst.setInt(1, sdsNum);
ResultSet rs = pst.executeQuery(sql);
while (rs.next()) {
int SDS_NUMBER = rs.getInt("SDS_NUMBER");
String PRODUCT_NAME= rs.getString("PRODUCT_NAME");
....
}

} else if ("sdsNumber".equals(tmp)) {
after I changed the first line to this everything works. I dont fully understand what difference that made and if someone could shine some light on it, I would appreciate it as I am slowly learning this.

Related

change data in SQL

I´ve created a table in SQL.
CREATE TABLE IF NOT EXISTS data (
id int NOT NULL AUTO_INCREMENT,
Username String,
Countdown double,
PRIMARY KEY(id)
)
Now I want to change the Countdown - field.
try {
final int i = 10; //my new var, which should saved in databank
PreparedStatement ps = connection.prepareStatement(""); //Dont know what to write in SQL here
ps.executeUpdate();
} catch(SQLException e) {
e.printStackTrace();
}
Example : Imagine my field with the field Username "example" has the Countdown 11 and now I want to change this value to 10.
If you want to use a prepared statement, you need to "prepare" your query first, then inject the values. More info here.
First, you need an UPDATE query.
String updateStatement =
"UPDATE data" +
"SET Countdown = ? " +
"WHERE Username = ?";
Then you can prepare your statement with:
PreparedStatement ps = connection.prepareStatement(updateStatement);
And add your values with:
ps.setInt(1, 11);
ps.setString(2, "example");
And you're ready to go!
ps.executeUpdate();

Cannot delete or update a parent row - Java

I teacher is trying to delete a row, which is used by a student.
But how can I delete this row anyway?
If the teacher wants to delete the lesson it should delete it anyway?
This is the function I have for the delete query:
con = DriverManager.getConnection ("jdbc:mysql://localhost:3307/lessons","root","");
String query = "DELETE FROM lessons WHERE Number= ?";
PreparedStatement pst = con.prepareStatement(query);
pst.setString(1,txtFieldNumber.getText());
pst.executeUpdate();
.
CREATE TABLE UserLogin(
Number INTEGER,
UserNumberINTEGER,
FOREIGN KEY (Number) REFERENCES termin(Number),
FOREIGN KEY (UserNumber) REFERENCES User(UserNumber)
);
CREATE TABLE lessons(
Number INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
LName VARCHAR(20)
);
CREATE TABLE User(
Name VARCHAR (20),
UserNUmber INTEGER NOT NULL PRIMARY KEY
);
You have to perform 2 separate deletes and in the right order using the same value for the Number parameter.
First delete from UserLogin with
DELETE FROM UserLogin WHERE Number = ?
And then use the command you have today
DELETE FROM lessons WHERE Number = ?
If you want to be sure both statements gets executed properly you can use manual commit like this
You can't use setString when the underlying column is int
Assuming your txtFieldNumber.getText() returns a number in String format, Try the following
pst.setInt(1,Integer.parseInt(txtFieldNumber.getText()));
Update:
Based on your question edit, looks like you are first trying to delete primary key in lessons which is being referenced in UserLogin table. This is the reason you're facing the error.
To overcome this, you may want to first delete in UserLogin table and then delete the corresponding rows in lessons table.
String query = "DELETE FROM UserLogin WHERE Number= ?";
PreparedStatement pst = con.prepareStatement(query);
pst.setInt(1,Integer.parseInt(txtFieldNumber.getText()));
pst.executeUpdate();
String query2 = "DELETE FROM lessons WHERE Number= ?";
pst = con.prepareStatement(query2);
pst.setInt(1,Integer.parseInt(txtFieldNumber.getText()));
pst.executeUpdate();
This should solve your issue

Java JDBC adding automatic value to database

I'm working with Java JDBC with Apache Derby data base.
I have a table called `company`` with the values :
id, comp_name, password, email.
This method should create a new row of company with name, password, and email received from the user but the ID should be given automatically from the database and increment itself each time a new company is added to the database.
I just can't figure out how to make this work, I obviously get a error
"column 'ID' cannot accept a NULL value."
because the update occours before the ID is setted.
Code:
public void createCompany(Company company) {
Connection con = null;
try {
con = ConnectionPool.getInstance().getConnection();
String sql = "INSERT INTO company (comp_name, password, email) VALUES (?,?,?)";
PreparedStatement pstmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
pstmt.setString(1, company.getCompName());
pstmt.setString(2, company.getPassword());
pstmt.setString(3, company.getEmail());
pstmt.executeUpdate();
ResultSet rs = pstmt.getGeneratedKeys();
rs.next();
company.setId(rs.getLong(1));
pstmt.getConnection().commit();
} catch (SQLException e) {
e.printStackTrace();
} finally {
ConnectionPool.getInstance().returnCon(con);
}
During creation of that table you have to write following DDL
CREATE TABLE MAPS
(
comp_id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
comp_name VARCHAR(24) NOT NULL,
password VARCHAR(26)
)
Ref : https://db.apache.org/derby/docs/10.0/manuals/develop/develop132.html
You're doing almost everything right, you just need to let the database assign an unique ID to each inserted row:
CREATE TABLE my_table (
id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
...
);
A problem could be that you made a mistake by creating your table.
You could create your table like this:
CREATE TABLE company
(
ID INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
comp_name VARCHAR(50),
email VARCHAR(50),
password VARCHAR (50)
)
IF you want other values to be not NULL you could add NOT NULL to their lines:
password VARCHAR (50) NOT NULL
Delte your old table and execute the the SQl above on your DB. After that you can use your code without changes.

How do I properly get a SQL Datetime back into my Java application?

I'm having trouble with retrieving queries from my SQL database. I can get the blasted things added to the database, but I'm having an inordinate amount of difficulties performing the reverse. Three things, in order:
The SQL Table itself:
CREATE TABLE patientInstructions (
id INT UNSIGNED AUTO_INCREMENT,
lastUpdated datetime NOT NULL,
PatientID BIGINT UNSIGNED NOT NULL,
HCPID BIGINT UNSIGNED NOT NULL,
OVid BIGINT UNSIGNED NOT NULL,
urlLink VARCHAR(250) NOT NULL,
linkInstructions VARCHAR(500) NOT NULL,
linkName VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
) AUTO_INCREMENT=1 ENGINE=MyISAM;
The method call that is failing (I'm getting -1L instead of the actual data value stored in the database, which is why I know there's a problem in the first place):
public String getLastUpdated(long ovID) throws DBException {
try {
return psiDAO.getLastUpdated(ovID);
} catch (myOwnException e) {
e.printStackTrace();
return "-1L";
}
}
And finally, the method call which is failing:
public String getLastUpdated(long ovId) throws DBException {
Connection conn = null;
PreparedStatement ps = null;
try {
conn = factory.getConnection();
ps = conn.prepareStatement("SELECT * FROM patientInstructions"
+ " WHERE ovId=?");
ps.setLong(1, ovId);
ResultSet rs = ps.executeQuery();
java.util.Date updated = new java.util.Date();
updated = rs.getTime("lastUpdated");
return updated.toString();
} catch (SQLException e) {
e.printStackTrace();
throw new DBException(e);
} finally {
DBUtil.closeConnection(conn, ps);
}
}
What Java object matches a SQL Datetime? I've tried rs.getTimestamp, rs.getDate, etc. but haven't had any more success (though I'm not ruling out that I botched those up either). Am I making a mistake transferring the data from the resultset back to Java object?
You must call ResultSet.next() on a ResultSet before accessing each row, including the first. You're not doing that here; the exception message should actually be telling you this.
There are three classes: java.sql.Date, java.sql.Time, and java.sql.Timestamp. I'm not sure which one most closely corresponds to a DATETIME in SQL. All three derive from java.util.Date, which is why you are able to assign the result of calling rs.getTime to one.
I don't have a setup here that would allow me to test it, but I would try using one of the types from java.sql.* and see what results that gives you.
Whoops! I posted my answer before Ernest's and I didn't even notice the missing rs.next(). That is definitely your problem, and I bet java.util.Date will work just fine for you, with that change.
Since your datatype is datetime, you will need to use getTimestamp()... see here for more datatype mapping information.
So, your code should look something like this:-
...
ResultSet rs = ps.executeQuery();
String updated = "";
if (rs.next()) {
updated = rs.getTimestamp("lastUpdated").toString();
}
rs.close();
ps.close();
return updated;
Please paste the exception here. You need to call ResultSet's next method before retrieving the values from the result set. Also, try java.sql.Timestamp lastUpdatedTimestamp = getTimestamp("lastUpdated")
If needed , you can convert timestamp to String later.

Value from last inserted row in DB [duplicate]

This question already has answers here:
How to get a value from the last inserted row? [duplicate]
(14 answers)
Closed 9 years ago.
Is there some way to get a value from the last inserted row?
I am inserting a row where the PK will automatically increase due to sequence created, and I would like to get this sequence number. Only the PK is guaranteed to be unique in the table.
I am using Java with a JDBC and Oracle.
I forgot to add that I would like to retrieve this value using the resultset below. (I have tried this with mysql and it worked successfully, but I had to switch over to Oracle and now I get a string representation of the ID and not the actually sequence number)
Statement stmt = conn.createStatement();
stmt.executeUpdate(insertCmd, Statement.RETURN_GENERATED_KEYS);
stmt.RETURN_GENERATED_KEYS;
ResultSet rs = stmt.getGeneratedKeys();
if(rs.next()){
log.info("Successful insert");
id = rs.getString(1);
}
The above snippet would return the column int value stored in a mysql table. But since I have switched over to Oracle, the value returned is now a strange string value.
What you're trying to do is take advantage of the RETURNING clause. Let's setup an example table and sequence:
CREATE TABLE "TEST"
( "ID" NUMBER NOT NULL ENABLE,
"NAME" VARCHAR2(100 CHAR) NOT NULL ENABLE,
CONSTRAINT "PK_TEST" PRIMARY KEY ("ID")
);
CREATE SEQUENCE SEQ_TEST;
Now, your Java code should look like this:
String insertSql = "BEGIN INSERT INTO TEST (ID, NAME) VALUES (SEQ_TEST.NEXTVAL(), ?) RETURNING ID INTO ?; END;";
java.sql.CallableStatement stmt = conn.prepareCall(insertSql);
stmt.setString(1, "John Smith");
stmt.registerOutParameter(2, java.sql.Types.VARCHAR);
stmt.execute();
int id = stmt.getInt(2);
This is not consistent with other databases but, when using Oracle, getGeneratedKeys() returns the ROWID for the inserted row when using Statement.RETURN_GENERATEDKEYS. So you need to use the oracle.sql.ROWID proprietary type to "read" it:
Statement stmt = connection.createStatement();
stmt.executeUpdate(insertCmd, Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
oracle.sql.ROWID rid = (oracle.sql.ROWID) rs.getObject(1);
But this won't give you the generated ID of the PK. When working with Oracle, you should either use the method executeUpdate(String sql, int[] columnIndexes) or executeUpdate(String sql, String[] columnNames) instead of executeUpdate(String sql, int autoGeneratedKeys) to get the generated sequence value. Something like this (adapt the value to match the index or the name of your primary key column):
stmt.executeUpdate(INSERT_SQL, new int[] {1});
ResultSet rs = stmt.getGeneratedKeys();
Or
stmt.executeUpdate(INSERT_SQL, new String[] {"ID"});
ResultSet rs = stmt.getGeneratedKeys();
While digging a bit more on this, it appears that this approach is shown in the Spring documentation (as mentioned here) so, well, I guess it can't be totally wrong. But, unfortunately, it is not really portable and it may not work on other platforms.
You should use ResultSet#getLong() instead. If in vain, try ResultSet#getRowId() and eventually cast it to oracle.sql.ROWID. If the returned hex string is actually the ID in hexadecimal flavor, then you can try converting it to decimal by Long#valueOf() or Integer#valueOf().
Long id = Long.valueOf(hexId, 16);
That said, Oracle's JDBC driver didn't support ResultSet#getGeneratedKeys() for a long time and is still somewhat troublesome with it. If you can't get that right, then you need to execute a SELECT CURRVAL(sequencename) on the same statement as you did the insert, or a new statement inside the same transaction, if it was a PreparedStatement. Basic example:
public void create(User user) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
Statement statement = null;
ResultSet generatedKeys = null;
try {
connection = daoFactory.getConnection();
preparedStatement = connection.prepareStatement(SQL_INSERT);
preparedStatement.setValue(1, user.getName());
// Set more values here.
int affectedRows = preparedStatement.executeUpdate();
if (affectedRows == 0) {
throw new SQLException("Creating user failed, no rows affected.");
}
statement = connection.createStatement();
generatedKeys = statement.executeQuery(SQL_CURRVAL);
if (generatedKeys.next()) {
user.setId(generatedKeys.getLong(1));
} else {
throw new SQLException("Creating user failed, no generated key obtained.");
}
} finally {
close(generatedKeys);
close(statement);
close(preparedStatement);
close(connection);
}
}
Oh, from your code example, the following line
stmt.RETURN_GENERATED_KEYS;
is entirely superfluous. Remove it.
You can find here another example which I posted before about getting the generated keys, it uses the normal getGeneratedKeys() approach.

Categories

Resources