I am trying to insert a date object into the database but it says im trying to insert an Integer. Here is my code:
public void insertAssignment(long studentId, String newAssignment, int ptsTotal, int ptsRecieved, String category, Date dueDate, String term, int yr) {
java.sql.Date temp = new java.sql.Date(dueDate.getTime());
try{
s.execute("INSERT INTO Assignments " +
"VALUES (" + studentId + ",'" + newAssignment + "'," + ptsTotal +
"," + ptsRecieved + ",'" + category + "'," + temp
+ ",'" + term + "'," + yr + ")");
System.out.println("Assignment inserted.");
}
catch(SQLException error){
System.err.println("Unable to insertAssignment.");
error.printStackTrace(System.err);
System.exit(0);
}
}
My error:
java.sql.SQLSyntaxErrorException: Columns of type 'DATE' cannot hold values of type 'INTEGER'.
To do this, use a prepared statement instead and use a setter.
Currently you flatten your date to a string value (which needs to be in the right format for the database for this to work) and lose that it is a date so the database needs to parse it. You avoid this using the prepared statement.
Related
I have a SpringBoot application where I use Repository class to query my Oracle DB table.
Here is how the query and associated function are defined :
#Query( value =" SELECT status "+
" FROM tb1 " +
" WHERE " +
" to_date(cob_Date,'dd-MON-yy') = to_date(:cobDate,'yyyy-mm-dd') " +
" AND business_Day ='BD3' " +
" AND intra_day ='INTRA_06' " +
" AND datasource_name =:datasource" +
" AND upper(status) = 'COMPLETED' " +
" AND frequency = 'MONTHLY' " +
" AND processed = 'Y' " +
" ORDER BY create_date desc FETCH FIRST 1 rows only"
, nativeQuery=true)
List<String> getImpalaJobStatus(#Param("intraDay") String intraDay,
#Param("businessDay") String businessDay,
#Param("cobDate") LocalDate cobDate,
#Param("datasource") String datasource);
If I run this query in SQL developer then I am getting my results back, however if I run it from my SpringBoot Application it returns nothing.
I suspect I am doing something wrong with the Date field "COB_DATE" and this clause under WHERE:
" to_date(cob_Date,'dd-MON-yy') = to_date(:cobDate,'yyyy-mm-dd') " +
I tried it as :
" cob_Date =:cobDate "
but it didn't work either.
That cobDate is being declared as a LocalDate in the method signature implies that you already have that value in date format. If so, then the call to to_date() in the query is not needed. Try binding the LocalDate value directly:
#Query( value =" SELECT status "+
" FROM tb1 " +
" WHERE " +
" to_date(cob_Date,'dd-MON-yy') = :cobDate " +
" AND business_Day ='BD3' " +
" AND intra_day ='INTRA_06' " +
" AND datasource_name =:datasource" +
" AND upper(status) = 'COMPLETED' " +
" AND frequency = 'MONTHLY' " +
" AND processed = 'Y' " +
" ORDER BY create_date desc FETCH FIRST 1 rows only"
, nativeQuery=true)
List<String> getImpalaJobStatus(#Param("intraDay") String intraDay,
#Param("businessDay") String businessDay,
#Param("cobDate") LocalDate cobDate,
#Param("datasource") String datasource);
Note that your Oracle JBDC driver should know how to marshall the LocalDate value to the database such that the query works.
I am trying to populate one table in my database with pretty complex data. For this, I am using a generator API (which gives me random data).
public void populateCrackers(){
PreparedStatement psm;
String queryJoke = "(SELECT jid FROM Jokes WHERE jid=?)";
String queryHat = "(SELECT hid FROM Hats WHERE hid=?)";
String queryGift = "(SELECT gid FROM Gifts WHERE gid=?)";
String query = "INSERT INTO Crackers(cid, name, jid, hid, gid, quantity) VALUES(" +
"?, " +
"?, " +
queryJoke + ", " +
queryHat + ", " +
queryGift + ", " +
"?)";
System.out.println(query);
String cracker_String = utils.JSONUtils.getJSON(crackerAPI, client);
JSONObject crackerJSON = new JSONObject(cracker_String);
JSONArray crackers = crackerJSON.getJSONArray("results");
for(int j=0; j<crackers.length(); j++){
try{
psm = connection.prepareStatement(query);
psm.setInt(1,crackers.getJSONObject(j).getInt("cid"));
psm.setString(2, crackers.getJSONObject(j).getString("cname"));
psm.setInt(3, crackers.getJSONObject(j).getInt("rjoke"));
psm.setInt(4, crackers.getJSONObject(j).getInt("rhat"));
psm.setInt(5, crackers.getJSONObject(j).getInt("rgift"));
psm.setInt(6, crackers.getJSONObject(j).getInt("cquantity"));
psm.execute();
System.out.println(crackers.getJSONObject(j).get("cid") + " "
+ crackers.getJSONObject(j).get("cname") + " "
+ crackers.getJSONObject(j).get("cquantity") + " "
+ crackers.getJSONObject(j).get("rjoke") + " "
+ crackers.getJSONObject(j).get("rhat") + " "
+ crackers.getJSONObject(j).get("rgift"));
}catch (Exception e){
e.printStackTrace();
}
}
}
This is the method that populates my "Crackers" tab. I am wondering if this be accepted as a prepared statement. When I run it in psql interactive command line tool, exactly that statement with some chosen ids (e.g INSERT INTO Crackers (cid, name, hid, jid, gid, quantity) VALUES('cid', 'name', (SELECT hid FROM Hats WHERE hid=11), (SELECT jid FROM Jokes where jid=99), (SELECT gid FROM Gifts WHERE gid=13), 5) it works flawlessly.
Does my preparedstatement break the Constraint?
Any ideas?
LATER EDIT: The inconsistency is the form of that null values can reach my Crackers table (e.g. Cracker(1, "hello", null, null, 3, 123) appears in the table.
There is nothing about Prepared statement. Constraint can be broken by parameters you set to it. And you can run your PLSQL statement as anonimous block in PreparedStatement as well.
Just surround it with BEGIN ... END. only one thing is different - for JDBC parameters are ? mark not :parameter as for PLSQL and there is no way to use named parameter.
That means if you need to use parameter more than once for JDBC you have to have that many ? marks and set all of them.
So, focus on parameters you pass to and their sequence.
The code is correct, though the prepared statement must be closed, and it would be better to create the statement once, before the for loop.
Now there is crackers.length() times a statement created but not closed. That might give problems.
Use the try-with-resouce syntax for automatic closing, irrespective of any exception or return.
try (PreparedStatement psm = connection.prepareStatement(query)) {
for (int j = 0; j < crackers.length(); j++) {
...
psm.executeUpdate();
And call executeUpdate instead of the more general execute. The resulting update count might be of interest (1/0).
I realised I had the wrong constraints on my table. I was letting null values in. There was nothing wrong with the prepared statement.
The right query to create the table is this one:
String createCrackersQuery = "CREATE TABLE Crackers(" +
" cid INTEGER," +
" name VARCHAR NOT NULL," +
" jid INTEGER NOT NULL," +
" hid INTEGER NOT NULL," +
" gid INTEGER NOT NULL," +
" quantity INTEGER NOT NULL," +
" CONSTRAINT Cracker_Primary PRIMARY KEY (cid)," +
" CONSTRAINT Cracker_Name_Unique UNIQUE(name)," +
" CONSTRAINT Joke_Foreign FOREIGN KEY (jid) REFERENCES Jokes(jid)," +
" CONSTRAINT Hat_Foreign FOREIGN KEY (hid) REFERENCES Hats(hid), " +
" CONSTRAINT Gift_Foreign FOREIGN KEY (gid) REFERENCES Gifts(gid)" +
")";
I want to insert a time which is taken from a textbox to the mysql database TIME column. I suppose I need to convert String to TIME like converting String to Date in mysql using "STR_TO_DATE" in the query. I looked for answers but I didn't get the answer I required.
Edit: SQL from comments:
"insert into schedules (
courseid,
batch,
subjectid,
teacherid,
stime,
etime,
date,
location,
building,
department,
hall,
status
) values ('" +
getCourse() + "','" +
getBatch() + "', '" +
getSubject() + "','" +
getTeacher() + "', '" +
getStime()+ "','" +
getEtime()+
"',STR_TO_DATE('" + getDate() + "','%d-%m-%Y'),'" +
getLocation() + "', '" +
getBuilding() + "', '" +
getDepartment()+ "', '" +
getHall() +
"','ACTIVE')"
As stated in comments Mysql accepts simple strings like '05:12:59' into TIME type columns but lets try to have another answer to it to. Check the format of date you get from textbox and edit Simple date format. You can try below.
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date parsedDate = dateFormat.parse(request.getParameter("textBoxName"));
Timestamp timestamp = new java.sql.Timestamp(parsedDate.getTime());//or you can assign this stuff to stime variable
I assume you are using preparedStatement as I think you will inserting many times. If so you can set the parameter like this.
preparedStatement.setTimestamp(1, timestamp);//1 is the index of parameter you can choose named parameters too
Also you can choose the to set stime and pass it in query using its relative getter.
Ok so I have an application that connects to a database that has a customer table. In the customer table I capture a range of different values. VH_ID is a foreign key to the vehicle table and the insurance_ID is also a foreign key to the insurance table.
Any ideas would be appreciated.
Edit
public CustomerInformation getCustomerInfo(String customerName) {
CustomerInformation info = new CustomerInformation();
ResultSet result;
try {
String sqlStatement = "SELECT "
+ DBStrings.C_NAME + ","
+ DBStrings.C_ADDRESS + ","
+ DBStrings.C_PHONENO + ","
+ DBStrings.C_EMAIL + ","
+ DBStrings.C_VH_ID + ","
+ DBStrings.C_VH_MODEL + ","
+ DBStrings.C_VH_YEAR + ","
+ DBStrings.C_VH_REGO + ","
+ DBStrings.C_VH_CHASSIS + ","
+ DBStrings.C_VH_VIN + ","
+ DBStrings.C_INSURANCE
+ " FROM " + DBStrings.CUSTOMER + " WHERE " + DBStrings.C_ID + " = " + this.getCustomerId(customerName);
result = statement.executeQuery(sqlStatement);
while (result != null && result.next()) {
info.setName(result.getString(DBStrings.C_NAME));
info.setAddress(result.getString(DBStrings.C_ADDRESS));
info.setPhoneNumber(result.getString(DBStrings.C_PHONENO));
info.setEmail(result.getString(DBStrings.C_EMAIL));
info.setRego(result.getString(DBStrings.C_VH_REGO) + "");
info.setChassis(result.getString(DBStrings.C_VH_CHASSIS) + "");
info.setVin(result.getString(DBStrings.C_VH_VIN) + "");
info.setVehicleModel(result.getString(DBStrings.C_VH_MODEL) + "");
info.setYear(result.getInt(DBStrings.C_VH_YEAR) + "");
info.setInsurance(this.getInsuranceFromId(result.getInt(DBStrings.C_INSURANCE)));
info.setVehicleMake(this.getVehicleFromId(result.getInt(DBStrings.C_VH_ID)));
}
} catch (SQLException ex) {
Logger.getLogger(Database.class
.getName()).log(Level.SEVERE, null, ex);
}
return info;
}
That is the new code with the ResultSet nested inside the method. Now I am getting the error:
SEVERE: null
java.sql.SQLException: ResultSet not open. Operation 'getInt' not permitted. Verify that autocommit is OFF.
at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
at org.apache.derby.client.am.ResultSet.getInt(Unknown Source)
at Database.Database.getCustomerInfo(Database.java:599)
Statement
connection = DriverManager.getConnection(connectionURL, "user", "pass");
statement = connection.createStatement();
Maybe you have column VH_MODEL twice in your query due to a "copy-paste accident" in the constants, i.e. another constant also expands to "VH_MODEL", specifically one of the columns following VH_MODEL in the get sequence. The DBMS would rename the result columns to make them unique in this case I guess. This would explain the strange situation where excuteQuery works while the getString fails.
Essentially the work around that I did to solve this issue was to create another method just specifically for retrieving the vehicle make. Seems a bit pointless but for the life of me I have no idea why it is not accepting it. The method has exactly the same contents for retrieving the data as in the first method.. Seems very odd.
String sqlStatement = "SELECT "
+ DBStrings.C_VH_ID
+ " FROM " + DBStrings.CUSTOMER + " WHERE " + DBStrings.C_ID + " = " + customerId;
rs = statement.executeQuery(sqlStatement);
if (rs != null && rs.next()) {
int vh_id = rs.getInt(DBStrings.C_VH_ID);
vehicle = this.getVehicleFromId(vh_id);
}
In my project I used txtAdvance 's key event.
double gtotal = Double.parseDouble(txtGtotal.getText());
double ad = Double.parseDouble(txtAdvance.getText());
double due = gtotal - ad;
txtDue.setText(String.valueOf(due));
And after last line run, I add a save button to save those data. Given below is that query.
public void saveInvoice(JTextField txtgtotal, JTextField txtAdvance, JTextField txtDue, JTextField txtInID) {
try {
db.putData("INSERT INTO indetails(inid, gtotal, advance, due) VALUES( '" + txtInID.getText() + "' ,'" + txtgtotal.getText() + "' , '" + txtAdvance.getText() + " ' " + " , '" + txtDue.getText() + "') ");
JOptionPane.showMessageDialog(null, txtAdvance.getText());
JOptionPane.showMessageDialog(null, "Invoice details saved");
}
catch (Exception e) {
JOptionPane.showMessageDialog(null, this.getClass().getName() + " first " + e);
}
}
I'm having MySql Data truncated for column 'advance' at row 1 . advance's data type is Double. But I can't find a way to put length.
(As an example
Column Name : iid, Data type : Int(18) {Primary key}
Column Name : inid, Data type : Int(18)
Column Name : gtotal, Data type : Double
Column Name : advance, Data type : Double
Column Name : due, Data type : Double
)
I'm using MySQL query browser . Question is when I'm adding 0 value to txtAdvance I'm having this error.
If the data you are trying to save have decimal points then change the datatype for advance as double with length 10,3 where 10 denotes number of digits and 3 denotes the number of decimal digits.
Use this query,
db.putData("INSERT INTO indetails(inid, gtotal, advance, due) VALUES(" + txtInID.getText() + "," + txtgtotal.getText() + "," + txtAdvance.getText() + "," + txtDue.getText()+")");
Instead of creating your query by hand, you should use db driver for it:
PreparedStatement putData = con.prepareStatement("INSERT INTO indetails(inid, gtotal, advance, due) VALUES(?,?,?,?)");
double gtotal = Double.parseDouble(txtGtotal.getText());
double ad = Double.parseDouble(txtAdvance.getText());
double due = gtotal - ad;
putData.setInt(1, inid);
putData.setDouble(2, gtotal);
putData.setDouble(3, ad);
putData.setDouble(4, due);
try {
putData.execute();
JOptionPane.showMessageDialog(null, txtAdvance.getText());
JOptionPane.showMessageDialog(null, "Invoice details saved");
}
catch (Exception e) {
JOptionPane.showMessageDialog(null, this.getClass().getName() + " first " + e);
}