My code is as follows:
read max(id) from table A
insert new row with new_id = max(id)+1 in table A
insert multiple rows in another table B, with this new_id.
So if there are multiple users trying to do this operation at the same time, they can get the same max(id) and insert two rows with the same id. Can I use TRANSACTION_SERIALIZABLE to prevent this, or is there another way to do it?
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.
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)
I want to get the primary key column value for the rows which were affected by query in Java. I am using MySql DB. Suppose query is like,
update user set pincode = 390023 where area like '%ABC Road%'
Then in java, I want the ids of each row (Primary key of each row) updated. Something that can be possible with Statement object in Java may be.
Select the rows just before you update them.
Use select id from user where area like '%ABC Road%'.
Remember to enclose those two operations in transaction to avoid row changes between those two.
SELECT id FROM user WHERE area LIKE '%ABC Road%';
or alternative way:
SET #ids = NULL;
UPDATE user
SET pincode = 390023
WHERE area LIKE '%ABC Road%'
AND (SELECT #ids := CONCAT_WS(',', id, #ids));
SELECT #ids;
I want to insert some 4K rows in the MySql db. I don't want to fire 4k 'insert' queries. Is there any way by which I can fire only one insert query to store those 4k rows in the db.
I searched on internet and everywhere I found that the users are doing bulk insert into the db from a file.
In my case, I have the data in the memory and I don't want to first write that data to a file to do bulk insert. If I do that then I will add delay in the program.
You could write a single insert query that would do several inserts in a single call to the database :
insert into your_table (field1, field2, field3)
values
(value1_1, value1_2, value1_3),
(value2_1, value2_2, value2_3),
(value3_1, value3_2, value3_3)
Here, with the example I've given, this single query would have inserted three rows in the table.
MySQL's LOAD DATA command might be useful to you: http://dev.mysql.com/doc/refman/5.5/en/load-data.html
With reference to Pascal's suggestion unless your command exceeds max_allowed_packet then you should be able to execute this query. In many cases it works best to create few smaller inserts with say 1000 rows in each.
You can execute your statements in batch, some code example can be found here.
Also, setAutoCommit(false), and call conn.commit(); after executeBatch() to minimise the number of commits.
Insert bulk more than 7000000 record in 1 minutes in database(superfast query with calculation)
mysqli_query($cons, '
LOAD DATA LOCAL INFILE "'.$file.'"
INTO TABLE tablename
FIELDS TERMINATED by \',\'
LINES TERMINATED BY \'\n\'
IGNORE 1 LINES
(isbn10,isbn13,price,discount,free_stock,report,report_date)
SET RRP = IF(discount = 0.00,price-price * 45/100,IF(discount = 0.01,price,IF(discount != 0.00,price-price * discount/100,#RRP))),
RRP_nl = RRP * 1.44 + 8,
RRP_bl = RRP * 1.44 + 8,
ID = NULL
')or die(mysqli_error());
$affected = (int) (mysqli_affected_rows($cons))-1;
$log->lwrite('Inventory.CSV to database:'. $affected.' record inserted successfully.');
RRP and RRP_nl and RRP_bl is not in csv but we are calculated that and after insert that.
In mySql you can use load data infile
LOAD DATA INFILE 'C:\MyTextFile'
INTO TABLE myDatabase.MyTable
FIELDS TERMINATED BY ','