MySQL select and update table at same time - java

I want to select a value one by one from my MySQL table and using this value get some value from different table. After getting the value I want to update my same table with this value.
Can I select and update the table at the same time?
I want to use Java to loop the table selecting values one by one from table.

You can set statement to be updatable. Then you can use the setters of the resultset to update any value.
You can also probably solve this in a single sql query but i'll have to see the tables to create an example.
Like this for instance:
update table_a a
set column_name=(select b.new_column_value from table_b b where b.uid=a.uid)
You can also add a where clause to the update to only perform it on some records in table_a

Related

Reading and wiring CSV File into database

I am implementing application specific data import feature from one database to another.
I have a CSV file containing say 10000 rows. These rows need to be inserted/updated into database.
I am using mysql database and inserting from Java.
There might be the case, where couple of rows may present in database that means those need to be updated. If not present in database, those need to be inserted.
One possible solution is that, I can read one by one line, check the entry in database and build insert/update queries accordingly. But this process may take much time to create update/insert queries and execute them in database. Some times my CSV file may have millions of records.
Is there any other faster way to achieve this feature?
I don't know how you determine "is already present", but if it's any kind of database level constraint (probably on a primary key?) you can make use of the REPLACE INTO statement, which will create a record unless it gets an error in which case it'll update the record that prevents it from being inserted.
It works just like INSERT basically:
REPLACE INTO table ( id, field1, field2 )
VALUES ( 1, 'value1', 'value'2 )
If a row with ID 1 exists, it's updated with these values; otherwise it's created.
Given that you're using MySQL you could use the INSERT ... ON DUPLICATE KEY UPDATE ... statement, which functions similarly to the SQL standard MERGE statement. MYSQL doc reference here and general Wikipedia reference to SQL MERGE functionality here. The statement would look something like
INSERT INTO MY_TABLE
(PRIMARY_KEY_COL, COL2, COL3, COL4)
VALUES
(1, 2, 3, 4)
ON DUPLICATE KEY
UPDATE COL2 = 2,
COL3 = 3,
COL4 = 4
In this example I'm assuming that PRIMARY_KEY_COL is a primary or unique key on MY_TABLE. If the INSERT statement would fail due to a duplicate value on the primary or unique key then the UPDATE clause is executed. Also note (on the MySQL doc page) that there are some gotcha's associated with auto-increment columns on an InnoDB table.
Share and enjoy.
Do you need to do this often or just once in a while?
I need to load csv files from time to time to a database for analysis and I created a SSIS-Datasolution with a Data Flow task which loads the csv-File into a table on the SQL Server.
For more infos look at this blog
http://blog.sqlauthority.com/2011/05/12/sql-server-import-csv-file-into-database-table-using-ssis/
Add a stored procedure in SQL for inserting. In the stored procedure use a try catch block to do the insert. If the insert fails do an update. Then you can simply call this method from your program.
Alternatively:
UPDATE Table1 SET (...) WHERE Column1='SomeValue'
IF ##ROWCOUNT=0
INSERT INTO Table1 VALUES (...)

SQL inserting data into two different tables

I'm reading user data from a Java GUI and trying to record it into two different database tables with a single statement. I'm fond of the 'insert into' statement, I just dont know how to enter data into two different tables (which are linked with a foreign key in the one of them), using inner joins and stuff..
Please, any help is welcome.
So far I've had all columns I need in one table but after normalising the database to 3NF I'm not sure of how to insert into all of them..
You need to use two insert statements. In the first statement you have insert data in the primary table and in the second statement you have to insert on secondary table ( where first table reference id will be used)
If you do opposite there will be constraint violation error from database.

Capture values from JDBC requests and use for next query

I'm trying to use Jmeter with about 10 queries per thread. All I want each thread to do is Insert into a player table using mysql auto increment. Then I want to use mysql
SELECT last_insert_id();
to grab the auto inc value and use it for the next query which is inserted into a player_game table.
How do I store the value returned and how do I call it in the next query?
I tried to save it in the variable name but can't seem to get it to insert correctly on the next query.
I then tried to call it using both ${player1id} and player1id but couldn't get it to work.
Is there a better way to go about this?
Or how can I store that value for the next JDBC request?
Both the queries
Insert into player...
Insert into player_game...
have auto increment on player_id and player_game_id
I then need to insert into a third table player_game_round and I need to insert the values from both player_id and player_game_id as such:
INSERT INTO player_game_round (round, player_score, player_id, player_game_id)....
You can directly do
INSERT into player_game(player_id, game_id) values(last_insert_id(), 1);

Making changes to my program after updating my database?

Sorry if my question is not specific or if it has been answered before. I tried looking for it and for a better way to ask but this is the most accurate way.
I have developed a program in Java in which I insert a new row into my database in the following way:
INSERT INTO table_name VALUES (?,?,?)
The thing is that I have this query in many parts of the program, and now I decided to add a fourth column to my table. Do I have to update EVERY SINGLE query with a new question mark in the program? If I dont, it crashes.
What is the best way to proceed in these cases?
YES.
you need to add extra ? (parameter placeholder) because you are using implicit INSERT statement. That means that you didn't specify the column names of the table to which the values will be inserted.
INSERT INTO table_name VALUES (?,?,?)
// the server assumes that you are inserting values for all
// columns in your table
// if you fail to add value on one column. an exception will be thrown
The next time you create an INSERT statement, make sure that you specify the column names on it so when you alter the table by adding extra column, you won't update all your place holders.
INSERT INTO table_name (Col1, col2, col3) VALUES (?,?,?)
// the server knows that you are inserting values for a specific column
Do I have to update EVERY SINGLE query with a new question mark in the program?
Probably. What you should do, while you're updating every single one of those queries, is to encapsulate them into an object, probably using a Data Source pattern such as a Table Data Gateway or a Row Data Gateway. That way you Don't Repeat Yourself and the next time you update the table, you only have one place to update the query.
Because of the syntax you've used, you might run some issues. I've referring to the lack of column names. Your INSERT queries will start failing as soon as you change your table structure.
If you had used the following syntax:
INSERT INTO table_name (C1, C2, C3) VALUES (?,?,?)
assuming your new column has a proper default value, then it would've work fine.

prevent period intersection in concurrent insert

I have a table with fields: name|...|start_date|end_date
My code now is:
select .... 'check for period intersection
insert .... 'if check succesfull insert new row
This code in one transaction.
When two users try to insert new record in the same time with same fields(and periods intersects) two records inserted.
But I want to avoid that inserting. First user must insert, other user must get conflict.
How can I do it ?
P.S. I use IBM DB2
Insert query which gets the data from select. In select the values selected will data that need to be inserted. The where clause can check for condition and should return null if check fails. So if I want to enter if id 5 is not in in table than
Insert into test1(val) select "test" from (select case when id = 5 then null else 5 end '1' from sysP where id =5) aa
This query will insert test in table test1 is id =5 is not there in sysP table
You could use an UK or select for update:
select .... 'check for period intersection FOR UPDATE WITH RS USE AND KEEP UPDATE LOCKS
Update:
Try locking the whole table before the select with:
LOCK TABLE TABLE_NAME IN EXCLUSIVE MODE
This way, the second transaction waits for the previous one to commit before select. The EXCLUSIVE MODE locks the select statements too, not only updates and inserts.
Update 2:
If "check for period intersection" uses only column from the same table as the one you're inserting into, then instead of select add a constraint check to your table. See http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=%2Fcom.ibm.db2.udb.admin.doc%2Fdoc%2Ft0004984.htm
Sounds like MERGE is exactly what you want, when combined with some error raising. I'm assuming you're using DB2 on Linux/Unix/Windows, but MERGE has been on the Mainframe DB2 since v9.1 as well.
MERGE INTO YOUR_TABLE YT
USING (
VALUES ('val1', 'val2', 'val3')
) MG(v1, v2, v3)
ON (TY.v1 = MG.v1)
WHEN MATCHED
SIGNAL SQLSTATE '70001'
SET MESSAGE_TEXT = 'Record already exists!'
WHEN NOT MATCHED THEN
INSERT(v1, v2, v3)
VALUES(MG.v1, MG.v2, MG.v3
ELSE IGNORE;
The USING clause can be used with provided values (like I have here), or it could be a sub-select. There are other examples on the Merge page on the Information Center that I linked above.

Categories