Cannot delete or update a parent row - Java - 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

Related

Foriegn Key Auto Increment

I have a database called college with two tables; Students and Courses. Course_fk is a foriegn key of the primary key in Courses table. Now in my query for saving data, i am expecting the Course_fk to be have the id of the primary key in Courses table whenever data is saved into Courses table.
I am running a multiple query (i.e entering data into Students and Courses table at the same time) But i get an error saying "Course_fk doesn't have any default value".
Students
ID
Name
Course_fk
Courses
ID
Course_Name
Query to save data
String sql = "Insert into Students(Name) values (?)";
String query = "Insert into Guardians(Course_Name) values (?) ";
try{
pst1 = conn.prepareStatement(query);
pst1.setString(1, course_name.getText());
pst1.execute();
pst = conn.prepareStatement(sql);
pst.setString(1, name.getText());
pst.execute();
Based on your information I think that this insert will work for you:
INSERT INTO students (course_fk)
SELECT id FROM courses WHERE course_name = "coursename";
I did not check this in MySQL database.

PostgreSQL Insertion in JAVA via JSP Incrementing Primary Key

I am writing a JSP application where the user enters a food item and it is entered in a PostgreSQL database. I had no problems implementing this when the user manually had to enter the next primary key, but I removed this ability so that the primary key would be automatically assigned when the enter button is clicked. I would like the query to fetch the current maximum FID (Food ID) and set the new food item's FID to the previous + 1.
try {
conn = ConnectionProvider.getCon();
String sql = "select fid from project.food order by fid desc limit 1";
pst = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
status = pst.getResultSetType();
f.setFood_id(status + 1);
pst = conn.prepareStatement("insert into project.food values(?,?,?,?,?,?)");
pst.setInt(1, f.getFood_id());
pst.setString(2, f.getFood_name()); //set name
pst.setInt(3, f.getCount()); //set count
pst.setInt(4, f.getPrice_per_item()); //set price
pst.setInt(5, f.getThreshold()); //set threshold
pst.setString(6, "false");
status = pst.executeUpdate();
conn.close();
pst.close();
} catch (Exception ex) {
System.out.println(ex);
}
return status;
}
The first food item is successfully inserted into the database in row 1006, instead of the 7th row, which is the first available in the database. Additionally, the second insert fails due to the failure of the primary key to the incremented by 1. The program again tries to insert the next tuple in the same row and thus violates the primary key constraint.
org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "food_pkey"
Detail: Key (fid)=(1006) already exists.
Make your primary key autoincrement in the database by declaring it SERIAL datatype (basically an auto incrementing INT) so a sequence is created to automatically assign values to it.
Then convert your update statement to specify all columns except for the primary key (i.e. insert into project.food(foo, bar, baz) values (?, ?, ?), and remove one ? placeholder and the pst.setInt(1,f.getFood_id()); line. This will insert values to all the other columns, and the primary key will be generated by the database.
This way you don't need to do a select when you want to insert (which was a really bad idea anyway), and you let the database do what it does best. You don't need to care about the value of the primary key after that.

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.

Java derby sql integer query

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.

Autoincrement issue - best way to add entries to the database and display them at the same time

I use a SQLite Database and a Java GUI. The information entered on the GUI will be added to a table in the database. This table contains an autoincrement. On the same time I want to display the information on the GUI and change it later.
creating the database:
stat.executeUpdate("create table t1(ROWID INTEGER PRIMARY KEY AUTOINCREMENT, Value);";
adding values to the database:
Statement stat = con.createStatement();
String sql = "insert into t1 values ($next_id,'"+value+');";
stat.executeUpdate(sql);
How can I save the ID in my program so that it will be the same as in the database and I have easy access to my database?
Edit:
I tried the solution mentioned in the comments and run into a NYI exception ...
String sql = "insert into t1 values($next_id,'"+value+"');";
PreparedStatement stmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
ResultSet res = stmt.getGeneratedKeys();
while (res.next()){
int id = res.getInt(1);
System.out.println(id);
}
con.commit();
tried also the solution of Russel and got another exception ("not implemented by SQLite JDBC driver"):
String sql = "insert into t1 values($next_id,'"+value+"');";
Statement stat = con.createStatement();
stat.executeUpdate(sql);
stat.executeUpdate("SELECT LAST_INSERT_ROWID() from t1;", Statement.RETURN_GENERATED_KEYS);
ResultSet res = stat.getGeneratedKeys();
while (res.next()){
int id = res.getInt(1);
System.out.println(id);
}
What did I wrong?
What about just calling SELECT LAST_INSERT_ID()? This returns the last auto-increment value generated for your connection (not affected by other clients' actions).
Alternately, looking at the Javadoc, it seems you should be able to do this with an ordinary Statement:
stat.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);
ResultSet keys = stat.getGeneratedKeys();
If you don't mind using an ORM library, try sormula. It will do all of the work for identity column for you. All that is required is #Column(identity=true) annotation on the POJO field that is to be auto incremented.
The test cases in org.sormula.tests.identity package shows you how. Sqlite test set up and sqlitejdbc-v056.jar jar is included. Change build.properties to run db.dir=sqlitejdbc.

Categories

Resources