I'm making a desktop app in Swing.
Here's the problem:
I have two tables - suppliers and items.
supplier supplierid(PK,AI),name,address,telephone
item itemid(PK,AI),supplier_supplierID(FK),name
Questions:
how do I insert in supplier and item tables at the same time? Does foreign key in items adds by itself or do I have to do it explicitly?
how do I add only item for a specific supplier? I was thinking about some list, dropdown menu to choose supplier -> get his PK and insert into item table.
I'm using Netbeans, MySQL
Thanks!
That depends on how you're trying to access your database.
Using a ORM like Hibernate and similar will do the most of the work for you because it's handling dependencies between Entities.
If you access your DB using plain JDBC, well you should insert the "rows" manually in the correct order.
So you should insert the supplier first and then the depending item.
If the supplier already exists, you should get it's id first and pass that value as supplier_supplierID when saving the item.
But this all has nothing to do with Spring!
You have to add the parent row (supplier) first, and then the item. Otherwise you will get an error.
When you add the supplier you use the new supplier_id as the value for the item.
This code is not the best but it works , first of all first insert some data in your primary table then you get that primary id you replace it with the 7 in the foreign key position in this code . so once it works then find a way to deal with the foreign key I did not work on it
try {
String url ="jdbc:mysql://localhost/dbtec";
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url,userdb,pass);
PreparedStatement statement = (PreparedStatement) conn.prepareStatement(" INSERT INTO supplier(name,address,telephone
) VALUES(?,?,?)");
statement.setString(1,"stackoverflow");
statement.setString(2,”15 newyork”);
statement.setString(3,"+19898989");
statement.executeUpdate();
statement.close();
/// Insert into another table
PreparedStatement statement2= (PreparedStatement) conn.prepareStatement("INSERT INTO item(supplierID,name) VALUES (?,?) ");
statement2.setString(1,"7");
statement2.setString(2,"Bruce");
statement2.executeUpdate();
statement2.close();
conn.close();
}
catch(SQLException e){
e.printStackTrace();
} catch (ClassNotFoundException ex) {
Logger.getLogger(newclient.class.getName()).log(Level.SEVERE, null, ex);
}
Related
I am working on an inventory database program using Java. I wrote a method that adds new product and quantity to the database. I am stuck on how I can prevent user from adding a duplicate entry to the database.
If the user enters a name that already exists in the database, the program should display an error message and show the main menu again. The program should not ask the user to enter the data again. The program should not replace the existing entry.
Thanks in advance!
public static void addData() {
try (Connection conn = DriverManager.getConnection(db_url, user, password)) {
String product = stringInput("Please enter the name of the product to store in inventory");
int quantity = intInput("Please enter the quantity of the product");
String addProduct = "INSERT INTO inventory VALUES (?,?)";
PreparedStatement insertProduct = conn.prepareStatement(addProduct);
insertProduct.setString(1, product);
insertProduct.setInt(2, quantity);
insertProduct.executeUpdate();
conn.close();
} catch(SQLException sqle){
sqle.printStackTrace();
System.exit(-1);
}
}
You can define UNIQUE constraint in your DB. Then if a duplicate entry is added it will throw an SQLIntegrityConstraintViolationException. Catch the exception and handle the error in your app.
May not be applicable to you, but just for your information spring-data exposes org.springframework.dao.DataIntegrityViolationException for achieving the same. When the same issue encountered spring-data wraps the underneath exception and re-throws a DataIntegrityViolationException so that the client can handle them inside the Error handling aspect using #ControllerAdvice.
you must query inventory table first to check if product name already exist, something like this
"select i.id from inventory where name=?"
then check with if clause that query has result or not, if true then do whatever needed, like show error...
In that case create a id column in your table and which should be unique or primary key. And handle exception SQLIntegrityConstraintViolationException to show the error message on app display.
Am creating a SQL Database for multiple users(Roughly 100 user), each records having nearly 15 fields in it.. In which the ID field is auto incremented...
Whenever a person Inserting a record to the database, it has to show "auto incremented ID" for that particular person, For this am using this code
PreparedStatement ppstmt = conn.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);
ppstmt.execute(sql,PreparedStatement.RETURN_GENERATED_KEYS);
ResultSet rs = ppstmt.getGeneratedKeys();
long key = 0;
if (rs != null && rs.next()) {
key = rs.getLong(1);
}
As of now its working fine but my doubt is when multiple users inserting the record at the same time, whether it will corresponding auto generated ID to each person..?
The statement will work correctly. The generated key returned will be the key generated by that execution of that statement for that user. These are SQL-defined semantics. Any implementation where it didn't work would be broken.
NB the result set cannot be null at the point you're testing it.
You have tagged oracle, so here is oracle's documentation on how retrieving generated keys works. A key piece of information is:
Auto-generated keys are implemented using the DML returning clause.
So it is worth looking at the documentation on how the returning clause works.
As you can see, this is guaranteed to return only data relevant to the just executed statement.
I would also like to point out that your use of a PreparedStatement is wrong. Once you have created the PreparedStatement from
PreparedStatement ppstmt = conn.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);
The next call should be to ppstmt.execute followed by ppstmt.getGeneratedKeys.
I have a store program in java and a database made in access. I already have 2 tables in my database which are the customers table and the products table.
I want to add an orders table wherein it's primary key is an autonumber and an order_line table to complete this app. I want to have tables like this..
customer(cust_id, name, ....)
orders(order_no, cust_id, date_purchased,...)
order_line(order_no, product_id, ...)
products(product_id, product_name, price,....)
When the customer purchased the products, i could insert new values to the orders table. The thing that is not clear to me is how could i insert also in the order_line table, because the order_no I created in access is of type autonumber.
Would I make a select statement first to get the order_no value to put it to the order_no in order_line's table? Or I need to put this in one query only.
Anyone with experience to this? Any advice is appreciated.
The insertion into orders and order_line table should happen in a single transaction. While doing so, if you are using plain JDBC to insert record into orders table, you can register the order_no as an OUT parameter in your CallableStatement and get the value after the statement is executed and use to set the order_no attribute on the order_line records.
// begin transaction
connection.setAutoCommit(false);
CallableStatement cs = connection.prepareCall(INSERT_STMT_INTO_ORDERS_TABLE);
cs.registerOutParameter(1, Types.INT);
int updateCount = cs.execute();
// Check the update count.
long orderNo = cs.getInt(1);
// CallableStatement csLine for inserting into order_line table
// for (OrderLine line: orderLines) {
// Set the orderNo in line.
// set paramters on csLine.
// csLine.addBatch();
// }
// run the batch and verify update counts
connection.commit();
// connection.rollback() on error.
The JDBC-way (if you like database-independence), is to use the getGeneratedKeys() method of statement.
Use setAutoCommit(false), then execute the first query with the option Statement.RETURN_GENERATED_KEYS (eg for PreparedStatement).
Then use the getGeneratedKeys() method to retrieve the key (note: reference by column name, as the exact implementation and number of returned columns depends on the driver implementation.
And execute the second statement with that retrieved key.
Finally, commit().
Why my pk will not auto ++ in my database? I want to let my ok auto +1 every time when I insert new details to the database...
public void generatePK(){
try{
rsCombineItem = stmtSearch.executeQuery("SELECT * FROM CombineItem;");
while(rsCombineItem.next()){
this.pk = rsCombineItem.getInt(1);
}
this.pk+=1;
}
catch(Exception e){
JOptionPane.showMessageDialog(null,e);
}
}
This is something that you need to set up on the database side, and not in your code. Set the column in your database as primary key, and to auto increment! See the example to see an example using SQL Server.
It's not clear what you're trying to do here at all. You talk about inserting but show a select statement; you talk about incrementing in the database but are incrementing in code; you have a method called generatePK which returns void; etc...
The short answer is that you should get the database to handle this. Every half-decent database has explicit support for primary keys, which you can have auto-assigned and auto-incremented. Simply set up the table to do this for you, and let the database choose the (after all, arbitrary) primary key as and when one is required.
I have a jtable on my GUI. (tableRealProperty). I need to add, delete and update the data inside the table. and this data are from a database where it has a primary key called ClientID. the columns inside the jtable are "Location" and "Area".
If i select a certain row from the jtable, it should be deleted as well as from the database, of course. My problem is that, when i click my delete button, not only the selected row is deleted but also all the data inside the table of that certain client..
here's my code for delete:
private void cmdDelRPropActionPerformed(java.awt.event.ActionEvent evt) {
String sql = "delete FROM tblrealProperty where tblrealproperty.ClientID = ?";
try {
pst = conn.prepareStatement(sql);
pst.setString(1, txtClientID.getText());
((DefaultTableModel)tableRealProperty.getModel()).removeRow(tableRealProperty.getSelectedRow());
pst.execute();
JOptionPane.showMessageDialog(null, "Deleted");
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, e);
}
}
If i select a certain row from the jtable, it should be deleted as
well as from the database, of course. My problem is that, when i click
my delete button, not only the selected row is deleted but also all
the data inside the table of that certain client..
This sounds like you have a foreign key to tblrealproperty set on the client table with cascade delete. That means, if a client is deleted from tblrealproperty, all corresponding data with a foreign key pointed to the deleted row in tblrealproperty are deleted as well. It is a feture inside DB to prevent inconstistencies.
This query will definitely delete all the rows with particular ClientID. You have to add another column to table in database say "index" which will be unique for each row in the table. then delete the row with this index:
`delete FROM tblrealProperty where tblrealproperty.index = ?`
For me works perfectly, don't forget to check if txtClientID is an index with autoincrement in your database. If your table have similar txtClientID, your delete command execute delete of all rows with the same txtClientID.