foreign key to auto update - mysql

I'm relatively new to relational databases and I'm not sure if what I want to do is possible. Could some one please tell me how to do this.
I have this named table1 where id is primary key
Id userName
1 A
2 C
3 F
and I have this table2 which is now empty, Id is a foreign key that REFERENCEd on table1 (Id)
Id amount
I want to set up my database so that the values in table1 id column are equal to the the values in tables2 id column and anytime an entry is added in table1 id column ,the same value is added table2 id column .
That change will also be reflected in table_1

Related

How to copy data of all columns of a row to another table except primary key column in mysql

I have two mysql table called table1 and table2 both having product_id as primary key with auto increment. I need to copy some of rows from table1 to table2 without copying product_id column value. Since I have 20+ columns in a single table I don't want to use it like
INSERT INTO table2('col1','col2'.....)
SELECT ('col1','col2'.....) FROM table1
WHERE product_id = 1;
Is there any way that I can use to copy data like below
INSERT INTO table2('product_id',*)
SELECT * FROM table2
WHERE product_id = 1;
Or any alternative methods ?
thank you

Add column on table with value dependent on foreign key

I'm not sure if there is already an answer for this but I didn't manage to find anything.
I have a table named Offer with a primary key ID and another column let's say Mask.
Offer -->
ID Mask
1 0
2 1
3 0
Let's say I have a completely different table Production that has a column-foreign key Offer_ID that references to the ID of table Offer.
I want to add a column Mask that will obtain the Mask value of the Offer row that the foreign key references to.
For example:
Production-->
ColA ColB Offer_ID Mask
.. .. 1 Here I want 0
EDIT:
The table Offers exists and so do its columns ID and Mask.Table Productions also exists,so does the column Offer_ID and is a foreign key to ID of tables Offers.I want to add a column Mask and set its values according to the Offer_ID column value.
The point is I don't want just to set the values properly,but I want whenever a new row is inserted to Productions the Mask column to get a value same with that of the row that foreign key(Offer_ID) references to.
You could join the two tables:
SELECT p.cola, p.colb, p.offer_id, o.mask
FROM production p
JOIN offer o ON p.offer_id = o.id

MYSQL Update all foreign key values

I have two identical tables that are located in two identical databases(with different name). I want to merge these two tables, but their primary keys are used in other tables,
these tables look like this:
Table A
id column1 column2 column3
___ ________ _______ ________
1 text text text
2 text text text
3 text text text
Table B
id column1 column2 column3
___ ________ _______ ________
2 text text text
3 text text text
4 text text text
tables that are linked to Table A
Link A
id column1 tableA_ID
___ ________ _______
1 text 2
2 text 3
3 text 4
Link B
id column1 tableA_ID
___ ________ _______
1 text 3
2 text 3
3 text 2
Please note, the tables have identical id's, this means when I do the merge, I have to change the id's of the second table. Remember the second table's primary keys are used in other tables.
I wrote this query to merge the two tables:
INSERT INTO db_A.`Table_A`(`column2`,`column3`)
SELECT `column2`,`column3` FROM db_B.`Table_B`;
This query will correctly copy the records of the second table to the first table.
Now I want to also move the data of the tables that are linked with Table B, I can use the same query, but now the foreign key will not match, because the ID they were linked with has been changed.
How do I update them so that the ID will match again?
NB: I do not have the ON UPDATE CASCADE constraint on those tables
I hope this make sense, I will try to improve this question so that everyone understands it.
Database Info
Type : MySQL
Engine: MyISAM
You can apply ON UPDATE CASCADE to each table with foreign keys related to TableB.id in second database temporary:
ALTER TABLE db2.other_tables_with_fk DROP FOREIGN KEY fk_to_TableB;
ALTER TABLE db2.other_tables_with_fk
ADD CONSTRAINT fk_to_TableB FOREIGN KEY (TableB_id)
REFERENCES TableB(id) ON UPDATE CASCADE;
and afterwards use the trick in Sami's Answer and then remove temporary changes like this:
ALTER TABLE db2.other_tables_with_fk DROP FOREIGN KEY fk_to_TableB;
ALTER TABLE db2.other_tables_with_fk
ADD CONSTRAINT fk_to_TableB FOREIGN KEY (TableB_id)
REFERENCES TableB(id);
Then your second database will be ready to merge with the first one.
For MyISM or situations that CASCADE is not supported by engine you can simulate it manually by defining Triggers:
CREATE TRIGGER trigger1
AFTER UPDATE
ON TableB
FOR EACH ROW
BEGIN
UPDATE other_tables_with_fk1 SET TableB_id = NEW.id WHERE TableB_id = OLD.id
UPDATE other_tables_with_fk2 SET TableB_id = NEW.id WHERE TableB_id = OLD.id
...
END
Even if triggers are not available you can simply increase id number of rows in second database by some custom amount(any amount greater than max row id which used in first database) in all tables including foreign key parent table at a same time:
UPDATE TableB t SET t.id = (t.id + 10000);
UPDATE related_table_1 t SET t.TableB_id = (t.TableB_id + 10000);
UPDATE related_table_2 t SET t.TableB_id = (t.TableB_id + 10000);
...
And then you can merge those databases.
my suggestion were:
you drop the foreign key constraint of LinkA in database1
increase the foreign key of the TableA:id AND LinkA:tableA_ID (the best way were with a join) by lets say 1000 (or how much rows you have in database2)
add the constraint again (optional)
import TableA and then LinkA to database2 from database1.
If you need more help, just ask.
Best Regards
====================================
Update. Example for the update of the ids:
UPDATE
Table_A, Link_A
SET
Table_A.id = Table_A.id + 1000,
Link_A.id = Link_A.tableA_ID + 1000,
FROM
Table_A JOIN Link_A
ON
Table_A.id = Link_A.tableA_ID
If both db are identical, I believe you should name it db_B.Table_A not db_B.Table_B to avoid confusion..but for now I go along with it
--get delta id, use biggest id from db_A and db_B
--to avoid failure because of updating to existing primary key
SELECT #dbBMax := MAX(id) FROM db_B.`Table_B`;
SELECT #dbAMin := MIN(id), #dbAMax := MAX(id) FROM db_A.`Table_A`;
SET #DeltaID := IF(#dbBMax > #dbAMax, #dbBMax, #dbAMax) - #dbAMin + 1;
--drop constraint
ALTER TABLE db_A.`Link_A` DROP FOREIGN KEY `constraint_name_A`;
ALTER TABLE db_A.`Link_B` DROP FOREIGN KEY `constraint_name_B`;
--update ids
UPDATE db_A.`Table_A` SET id = id + #DeltaID;
UPDATE db_A.`Link_A` SET tableA_ID = tableA_ID + #DeltaID;
UPDATE db_A.`Link_B` SET tableA_ID = Link_A.tableA_ID + #DeltaID;
--merge tables
--assume id is auto-increment, don't use auto-increment value,
--so id manually inserted
INSERT INTO db_A.`Table_A`(`id`, `column1`, `column2`,`column3`)
SELECT `id`, `column1`, `column2`,`column3` FROM db_B.`Table_B`;
--assume id is auto-increment, use it, don't insert manually
INSERT INTO db_A.`Link_A`(`column1`, `tableA_ID`)
SELECT `column1`, `tableA_ID` FROM db_B.`Link_A`;
--assume id is auto-increment, use it, don't insert manually
INSERT INTO db_A.`Link_B`(`column1`, `tableA_ID`)
SELECT `column1`, `tableA_ID` FROM db_B.`Link_B`;
This code may add big leap on id at db_B.Table_B if db_A.Table_A have much more data that db_B.Table_B..that can be fixed easily before/after merge table..but I think its optional..
A simple way would be to update the TableB's IDs to unique range and then do the merge. If your foreign keys are properly set to cascade the change, your database will stay consistent through this operation.
You don't need to do any changes to the database schema this way, so there is no point in time when the data is not calid. You can also be sure that the IDs won't clash. Easiest way to find unique values is to take the maximum of the ID in TableA and add that to the IDs in TableB.

SQL Syntax using CONCAT

I have a table T1 with some fields like
id,key_id ,name,date etc..
id is a auto incrementing field
key_id is a value obtained from id like prefix/id
Prefix is constant for all the rows and just id changes which is the id for the corresponding row..
It looks like something like this
$sql = " ALTER TABLE T1 AUTO_INCREMENT = 1234567890,
ADD id BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT ";
UPDATE T1
SET key_id = CONCAT('12.345','/',id)
Now due to some reasons i want to create a new table T2 which would be the parent of T1 and id would be the primary key T2 and Key_id would become primary key of T1. T2 should also include other two fields like key_id and name..
ok the main reason for parent table is : i might create another table T3 which will also have id and id should have different values for T1 and T3 so i want to maintain a master table which has id as a primary key and other child tables will fetch the ids only from master table..
How can I do this?
Why would you want to store a redundant data in another column "key_id"?
Since the prefix is constant, the id is enough. Perform the concatenation in your code.
Also, that way, you can have id as primary key for both tables and get the key_id by prefixing the "Prefix".

MySQL, two columns both set to the primary key

For the sake of simplicity lets say I have a table with 3 columns; id, parent_id and name. In this table id is my auto-incrementing primary key. I want to group multiple names together in this table, to do this all names in a group will share the same parent_id. If I am inserting the first name in the group I want the id=parent_id, if i am inserting another name I want to specify a specific parent_id to place that name into a specific group. It would be nice if I could define a default for that column to be the same as the id, if I specify a value for parent_id in the insert query then I would like it to use that value. I know you can set a default to be a specific static value, but can you specify the default to be the same as that row's auto-incrementing primary key? Perhaps this is a job for a trigger or stored procedure?
(I know I could obtain the primary key generated by the last insert and then update the table, but that's 2 quires I'd rather not burn.)
Thanks!
This is a job of a trigger!
CREATE TRIGGER NAME1 AFTER INSERT ON TABLE1
BEGIN
UPDATE TABLE1 SET parent_id = id WHERE (parent_id IS NULL OR parent_id = '');
END;
INSERT INTO TABLE1 (id,parent_id) VALUES (null,null); -- parent_id will be equal to id
INSERT INTO TABLE1 (id,parent_id) VALUES (null,'1'); -- parent_id will be 1
INSERT INTO TABLE1 (id,parent_id) VALUES (null,'2'); -- parent_id will be 2