how get next autonumber from one column jdbc database? - java

I am using an access mdb file as my database . Inside the table in my database I use id as autonumber. Now. I wanted to know how can i get the next generated auto number field in access database to put in java JTextField!

To get next number you can insert a "blank" row and use the number that was generated for it.
If your insert statement is stmt:
int nextKey = 0;
ResultSet keys = stmt.getGeneratedKeys();
if (keys.next())
{
nextKey = keys.getInt(1);
}
See statement.getGeneratedKeys()
Alternatively you could generate new id number with
SELECT MAX(id)+1 FROM yourTable
though this doesn't guarantee that the number will stay unused (by some other query) before you do anything with it.

Related

Get a specific column of the updated rows

I need to know how to execute an update in JDBC with Oracle database backend and retrieve values for a specific column of the records that have been updated. The column that I am interested in is part of a composite primary key, e.g. COL_NAME in the example below.
I have tried the following:
String query = "UPDATE T1 SET COL_ABC = 'A'"; // Simplified
statement = conn.prepareStatement(query.toString(), new String[] { "COL_NAME" });
ResultSet rs = statement.getResultSet();
while (rs.next()) {
rs.getLong("COL_NAME");
}
But statement comes back as null.
I am not sure how to utilize RETURNING INTO in this case unless converting this whole thing into an anonymous PL/SQL block, if it is indeed a possible solution.
Please note that I need a list of the values from this column from all the records that have been updated.

Retrieving Primary Key Generated By Trigger (Java)

Here's what I'm attempting to do. I have a Java program that decomms a telemetry stream into the individual raw fields. I am passing these raw fields values into a MySQL table where each column is one of the fields. In this database I also have a view that grabs all the telemetry data and calculates a few new derived columns based on raw data (e.g. raw counts to engineering units). In my Java program, after insertion I would like to grab the corresponding row from the VIEW (raw + derived) and pass that data along elsewhere.
Originally I thought I could simply insert the raw data into the VIEW and have the row returned to me in a ResultSet in the Java program. Unfortunately the data isn't returned in a ResultSet.
What I'm attempting to do now is insert the raw data into the table (this part works), get the primary key, then lookup the row from the VIEW. The part I'm struggling with is retrieving the primary key from the INSERT. I'm using a PreparedStatement generated from my Connection object and have supplied it with Statement.RETURN_GENERATED_KEYS. However, when I call getGeneratedKeys() on my statement after I call executeUpdate() my ResultSet is always empty. I can watch it insert the rows into the table while it's running...what am I doing wrong?
Can I not retrieve the generated primary key in this fashion if the primary key is generated via a trigger?
UPDATE: I've tried swapping out the Statement.RETURN_GENERATED_KEYS for a String array with the name of the primary key column, but that doesn't seem to work either.
I apologize for not including my code, but it would be difficult for me to do so. I've attempted to describe what I'm doing to the best of my abilities.
Ive seen this in another post. That claimed to work. Is this what yours looks like?
Statement stmt = db.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
numero = stmt.executeUpdate();
ResultSet rs = stmt.getGeneratedKeys();
if (rs.next()){
risultato=rs.getInt(1);
}
I have used SP's and here is an example of what I did. I used an in/out parm to get it back...
CREATE DEFINER=`scaha`#`localhost` PROCEDURE `updateprofile`(
IN in_idprofile INT(10),
IN in_usercode VARCHAR(50),
IN in_pwd VARCHAR(50),
IN in_nickname VARCHAR(50),
IN in_isactive tinyint,
IN in_updated timestamp,
OUT out_idprofile INT(10))
BEGIN
/* If the idprofile is < 1 then we insert a new record.. */
/* otherwise its an update */
if (in_idprofile < 1) then
insert into scaha.profile (usercode, pwd, nickname, isactive,updated) values (in_usercode,in_pwd,in_nickname,in_isactive,in_updated);
SET out_idprofile = LAST_INSERT_ID();
else
update scaha.profile set usercode = in_usercode, pwd = in_pwd, nickname = in_nickname, isactive = in_isactive, updated = in_updated
where idprofile = in_idprofile;
SET out_idprofile = in_idprofile;
end if;
END

How to get Auto Generated ID from SQL Table when multiple users working simultaneously

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.

Deleting rows in linked MySQL tables and decrementing count in another table

I am trying to create (java-based) messaging webapp. The messages are stored using MySQL using three tables:
'messages': has two columns, an id primary key ('idmessage') and the message ('message').
'tags': The user also inputs a tag associated with their message. This has two columns - the tag (which is also a primary key) and a count ('count').
'message_tag_link': Since there is a many-to-one relationship between messages and tags I have a third link table. This has two columns, both foreign keys to the messages ('fk_idmessage') and tags tables’ ids ('fk_tag').
Inserting messages into the database works fine. I use these following lines in Java:
pst1 = connection.prepareStatement("INSERT INTO messages(message) VALUES (?)");
pst2 = connection.prepareStatement("INSERT INTO tags(tag,count) VALUES (?,1) ON DUPLICATE KEY UPDATE count = count + 1");
pst3 = connection.prepareStatement("INSERT INTO message_tag_link(fk_idmessage,fk_tag) VALUES (? , ?)");
As can be seen ‘count’ increments in pst2 every time a duplicate tag entry is made.
I am trying to work out how to fully delete a message. I have the on delete cascade description on my foreign keys in my link table’s columns but am not sure what to do next. For a given 'messageid' I need to:
Delete a row in 'messages' table
Delete the associated row in the 'message_tag_link' table
Decrement the count value in the 'tags' table when a message deletion is successful, or delete this row entirely if count becomes zero.
Is it possible to do all this within MySQL using a Java PreparedStatement? Any pointers much appreciated. I am a total MySQL novice, so please be kind!
These queries should do what you need. ? in each query should be the message id that is to be deleted
//Update count
UPDATE tags SET `count` = `count` - 1 WHERE tag_id IN (SELECT fk_tag FROM message_tag_link WHERE fk_idMessage = ?);
//Remove link
DELETE FROM message_tag_link WHERE fk_idmessage = ?;
DELETE FROM messages WHERE id = ?;
//Remove unused tags
DELETE FROM tags WHERE `count` = 0;
As you've found out however maintaining a count can be annoying. Better is to use the link itself.
SELECT COUNT(fk_idmessage) AS msgcount FROM message_tag_link WHERE fk_tag = ?;
Also you can add a CASCADE so that when messages are deleted the tag link gets deleted too (see here). Be careful with this behavior however).
This solution still leaves tags with no messages but you can remove these using the query:
DELETE FROM tags t WHERE NOT EXISTS (SELECT 1 FROM nessage_tag_link WHERE t.tag_id = fk_tag)

How can I insert new values into two related tables?

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().

Categories

Resources