Trigger for update from one database to another database - mysql

I have two different database DB1 and DB2. Each has two different tables Table A and Table B respectively. So in case If any new row generates in table B I want trigger fire which gives me date and time in table A at same time when new row generated in table B. Now I have created one trigger as below but it's working.
DELIMITER $$
USE `DB2`$$
DROP TRIGGER /*!50032 IF EXISTS */ `trigger_update_date_time_table_A`$$
CREATE
/*!50017 DEFINER = 'root'#'%' */
TRIGGER `trigger_update_date_time_tableA` AFTER INSERT ON table_B
FOR EACH ROW
BEGIN
UPDATE DB1.table_A SET Date = CURRENT_TIMESTAMP WHERE id = NEW.id
END;
$$
DELIMITER ;

You are going to have to be a bit more specific about why you think the trigger does not produce the expected results with an example. Here's and example of how you could do that.BTW if you work your way through this you will see the trigger works as coded.
MariaDB [SANDBOX]> USE SANDBOX;
Database changed
MariaDB [SANDBOX]> SHOW CREATE TABLE T;
+-------+---------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------------------------------------+
| T | CREATE TABLE `t` (
`ID` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+---------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
MariaDB [SANDBOX]> USE TEST;
Database changed
MariaDB [TEST]> SHOW CREATE TABLE TEST.T;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| T | CREATE TABLE `t` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`price` int(11) DEFAULT NULL,
`tax` int(11) DEFAULT NULL,
`pricetax` int(11) AS (price + price *tax/100) VIRTUAL,
`DATE` date DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=latin1 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
MariaDB [TEST]> USE SANDBOX;
Database changed
MariaDB [SANDBOX]> SHOW CREATE TRIGGER T;
+---------+--------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| Trigger | sql_mode | SQL Original Statement | character_set_client | collation_connection | Database Collation |
+---------+--------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| T | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION | CREATE DEFINER=`root`#`localhost` TRIGGER T AFTER INSERT ON T
FOR EACH ROW
BEGIN
UPDATE TEST.T SET Date = CURRENT_TIMESTAMP WHERE id = NEW.id ;
END | utf8mb4 | utf8mb4_general_ci | latin1_swedish_ci |
+---------+--------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)
MariaDB [SANDBOX]> TRUNCATE TABLE T;
Query OK, 0 rows affected (0.22 sec)
MariaDB [SANDBOX]> SELECT * FROM T;
Empty set (0.00 sec)
MariaDB [SANDBOX]> UPDATE TEST.T SET DATE = NULL WHERE ID = 999;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [SANDBOX]> SELECT ID,DATE FROM TEST.T;
+-----+------+
| ID | DATE |
+-----+------+
| 1 | NULL |
| 999 | NULL |
+-----+------+
2 rows in set (0.00 sec)
MariaDB [SANDBOX]> INSERT INTO T (ID) VALUES (999);
Query OK, 1 row affected (0.02 sec)
MariaDB [SANDBOX]> SELECT ID,DATE FROM TEST.T;
+-----+------------+
| ID | DATE |
+-----+------------+
| 1 | NULL |
| 999 | 2018-09-13 |
+-----+------------+
2 rows in set (0.00 sec)

Related

How to modify a column to insert consequtive numbers?

So I have a table where a column that was given an auto_increment value accidentally got started form 300 instead of 1,2,3,4......i'm a beginner and i do not know how to change it back to 1,2,3,4......screenshot of table
how to change the 307, 308 to 1,2,3,4...?
I tried to update the table but that did not work.
Step-1) First take backup of your table data.
Step-2) Truncate the table by using the below SQL query.
TRUNCATE TABLE [Your_Table_Name];
Step-3) then again insert the into your table using backup data.
Alter table to drop the auto_increment, update, alter table to add the auto_increment
drop table if exists t;
create table t
( id int auto_increment primary key, val int);
insert into t values
(307,1),(308,1),(309,1),(310,1),(311,1);
alter table t
modify column id int;
#drop primary key;
show create table t;
update t
set id = id - 306;
alter table t
modify column id int auto_increment;
show create table t;
https://dbfiddle.uk/eBQh6cj8
With MySQL 8.0 you can use a window function to calculate the row numbers and then update the table:
mysql> select * from t;
+-----+------+
| id | val |
+-----+------+
| 307 | 1 |
| 308 | 1 |
| 309 | 1 |
| 310 | 1 |
| 311 | 1 |
+-----+------+
mysql> with cte as ( select id, row_number() over () as rownum from t )
-> update t join cte using (id) set id = rownum;
Query OK, 5 rows affected (0.00 sec)
Rows matched: 5 Changed: 5 Warnings: 0
mysql> select * from t;
+----+------+
| id | val |
+----+------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 1 |
| 5 | 1 |
+----+------+
Then make sure the next id won't be a high value:
mysql> alter table t auto_increment=1;
You can try to set the auto_increment to 1, MySQL will automatically advances that to the highest id value in the table, plus 1.
Be aware that this doesn't guarantee subsequent rows will use consecutive values. You can get non-consecutive values if:
You insert greater values explicitly, overriding the auto-increment.
You roll back transactions. Id values generated by auto-increment are not recycled if you roll back.
You delete rows.
Occasionally InnoDB will skip a number anyway. It does not guarantee consecutive values — it only guarantees unique values. You should not rely on the auto-increment to be the same as a row number.
Here is a one approach to your problem.
Please take note of the following points before proceeding:
Take backup of your table in-case things do not go as expected.
Below test case has been performed on MySQL 5.7 and MyISAM Engine.
Step1: Generating dummy test table as per your test case.
mysql> CREATE TABLE t (
-> `Id` int(11) NOT NULL AUTO_INCREMENT,
-> `product_id` int(11) DEFAULT 0,
-> PRIMARY KEY (`Id`)
-> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.03 sec)
-- Inserting dummy data
mysql> INSERT INTO t VALUES (300,1);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO t VALUES (302,1);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO t VALUES (305,1);
Query OK, 1 row affected (0.00 sec)
-- Checking auto_increment value
mysql> show create table t;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t | CREATE TABLE `t` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(11) DEFAULT '0',
PRIMARY KEY (`Id`)
) ENGINE=MyISAM AUTO_INCREMENT=306 DEFAULT CHARSET=latin1 |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> INSERT INTO t (product_id) VALUES (2);
Query OK, 1 row affected (0.01 sec)
-- Below is the resultant table for which we need Id starting from 1,2,3 and so on...
mysql> SELECT * FROM t;
+-----+------------+
| Id | product_id |
+-----+------------+
| 300 | 1 |
| 302 | 1 |
| 305 | 1 |
| 306 | 2 |
+-----+------------+
4 rows in set (0.00 sec)
Step2: Remove AUTO_INCREMENT for the column and set the Ids manually.
-- Remove AUTO_INCREMENT
mysql> ALTER TABLE t MODIFY COLUMN Id int(11) NOT NULL;
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
-- Set the Id manually starting from 1
mysql> SET #i = 0;UPDATE t SET id = #i :=#i +1;
Query OK, 0 rows affected (0.00 sec)
Query OK, 5 rows affected (0.00 sec)
Rows matched: 5 Changed: 5 Warnings: 0
-- Below is the updated table with Id starting from 1,2,3 and so on...
mysql> SELECT * FROM t;
+----+------------+
| Id | product_id |
+----+------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
+----+------------+
5 rows in set (0.00 sec)
Step3: Enable AUTO_INCREMENT again for future record insertions.
-- Enable AUTO_INCREMENT again for future record insertions.
mysql> ALTER TABLE t MODIFY COLUMN Id int(11) NOT NULL AUTO_INCREMENT;
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
-- Set the AUTO_INCREMENT value to continue from highest value of id in the table.
mysql> SELECT MAX(id+1) FROM t;
+-----------+
| MAX(id+1) |
+-----------+
| 6 |
+-----------+
1 row in set (0.00 sec)
mysql> ALTER TABLE t AUTO_INCREMENT=6;
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
-- Table is successfully modified and will have future records inserted with no gaps in Id's
mysql> INSERT INTO t (product_id) VALUES (5);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM t;
+----+------------+
| Id | product_id |
+----+------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 5 |
+----+------------+
6 rows in set (0.00 sec)
The DBCC CHECKIDENT management command is used to reset identity counter
DBCC CHECKIDENT (table_name [, { NORESEED | { RESEED [, new_reseed_value]}}])
[ WITH NO_INFOMSGS ]
EXample:
DBCC CHECKIDENT ('TestTable', RESEED, 0)
GO
many times we need to just reseed to next Id available
declare #max int
select #max=max([Id]) from [TestTable]
if #max IS NULL --check when max is returned as null
SET #max = 0
DBCC CHECKIDENT ('[TestTable]', RESEED, #max)
This will check the table and reset to the next ID.
You can get help from the link below:
Reset identity seed after deleting records in SQL Server
My mother says: the mountain that can be seen is not far away, don't stop trying

Converting from VARCHAR to BINARY(16) in MySQL?

I have as table with this column and type:
sales_channel_id BINARY(16)
In the row I have this value: 5DBACA1114B24872ACCFE679037DF670
I have written this value into another table, but this time the table column has the type VARCHAR(255). In the table I see this value: 5dbaca1114b24872accfe679037df670 (no capitals).
Now I have created another table with a column of type BINARY(16). When I make something like this to transform the data from the varchar column to the new column like this:
INSERT INTO
setting_sales_channel (sales_channel_id)
SELECT sales_channel_id from mcn_setting
I get the error: Query 1 ERROR: Data too long for column 'sales_channel_id' at row 1
Why does this happen and how can I transfer the data from the VARCHAR column into the new column which is of type BINARY(16)?
Try this.
change your query to:
INSERT INTO
setting_sales_channel (sales_channel_id)
SELECT CONVERT(sales_channel_id,BINARY(16)) from mcn_setting;
sample (MariaDB)
MariaDB [bernd]> show create table b;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| b | CREATE TABLE `b` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`bbinary` binary(16) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)
MariaDB [bernd]> show create table bs;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| bs | CREATE TABLE `bs` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`bvarchar` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)
MariaDB [bernd]> SELECT * from b;
Empty set (0.002 sec)
MariaDB [bernd]> SELECT * from bs;
+----+----------------------------------+
| id | bvarchar |
+----+----------------------------------+
| 1 | 5dbaca1114b24872accfe679037df670 |
+----+----------------------------------+
1 row in set (0.000 sec)
MariaDB [bernd]>
MariaDB [bernd]> INSERT INTO b (bbinary)
-> SELECT CONVERT(bvarchar,BINARY(16)) FROM bs;
Query OK, 1 row affected, 1 warning (0.003 sec)
Records: 1 Duplicates: 0 Warnings: 1
MariaDB [bernd]> SELECT * from bs;
+----+----------------------------------+
| id | bvarchar |
+----+----------------------------------+
| 1 | 5dbaca1114b24872accfe679037df670 |
+----+----------------------------------+
1 row in set (0.000 sec)
MariaDB [bernd]>
In my case it worked when using UNHEX now. The result looked like this:
INSERT INTO setting_sales_channel (sales_channel_id)
SELECT UNHEX(sales_channel_id) from setting;

How to update or change auto increment column value in Mysql

I have a table eav_attribute which have a below structure,
I have mistakenly deleted one record from this table with auto increment attribute id column with value 961.
Now I want that column again with same attribute id value.
But when I am inserting that column it is adding with auto increment value i.e. around 1500.
I want to add new coulmn with attribute id 961
I tried to change set AUTO_INCREMENT to 961 before adding column.
ALTER TABLE eav_attribute AUTO_INCREMENT = 961;
But its not working. Please provide any suggestion.
You can override the auto increment column. For example
MariaDB [sandbox]> drop table if exists t;
Query OK, 0 rows affected (0.14 sec)
MariaDB [sandbox]> create table t (id int auto_increment primary key,val varchar(1));
Query OK, 0 rows affected (0.27 sec)
MariaDB [sandbox]> insert into t (val) values
-> ('a'),('b'),('C');
Query OK, 3 rows affected (0.03 sec)
Records: 3 Duplicates: 0 Warnings: 0
MariaDB [sandbox]>
MariaDB [sandbox]> select * from t;
+----+------+
| id | val |
+----+------+
| 1 | a |
| 2 | b |
| 3 | C |
+----+------+
3 rows in set (0.00 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> delete from t where val = 'b';
Query OK, 1 row affected (0.03 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> select * from t;
+----+------+
| id | val |
+----+------+
| 1 | a |
| 3 | C |
+----+------+
2 rows in set (0.00 sec)
MariaDB [sandbox]> insert into t values (2,'b');
Query OK, 1 row affected (0.02 sec)
MariaDB [sandbox]> select * from t;
+----+------+
| id | val |
+----+------+
| 1 | a |
| 2 | b |
| 3 | C |
+----+------+
3 rows in set (0.00 sec)
MariaDB [sandbox]> show create table t;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t | CREATE TABLE `t` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`val` varchar(1) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
I would strongly advice you test this thoroughly...

How to implement an auto_increment composite primary key with MySQL InnoDB?

I have a table which has a composite primary key made up of one non-auto_increment column and one auto_increment column. The auto_increment column needs to increment individually for each of the non-auto_increment column values (more on this later). The storage engine is InnoDB. I don't wish to lock the table because of performance concerns. After inserting a value, a means to retrieve the last auto_increment value must be available.
The below script works at first, but the last INSERT results in id, checkingaccounts_id is 3, 2, but 1, 2 is desired. This is what I meant by The auto_increment column needs to increment individually for each of the non-auto_increment column values
Trigger and Stored Procedures are both acceptable, and so is a PHP/PDO application solution which somehow mimics the MySQL auto_increment behavior.
mysql> EXPLAIN checkingaccounts;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| data | varchar(45) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> EXPLAIN checks;
+---------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| checkingaccounts_id | int(11) | NO | PRI | NULL | |
| data | varchar(45) | YES | | NULL | |
+---------------------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> INSERT INTO checkingaccounts(id, data) VALUES(0,'bla');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO checkingaccounts(id, data) VALUES(0,'bla');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM checkingaccounts;
+----+------+
| id | data |
+----+------+
| 1 | bla |
| 2 | bla |
+----+------+
2 rows in set (0.00 sec)
mysql> INSERT INTO checks(id,checkingaccounts_id,data) VALUES(0,1,'bla');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO checks(id,checkingaccounts_id,data) VALUES(0,1,'bla');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM checks;
+----+---------------------+------+
| id | checkingaccounts_id | data |
+----+---------------------+------+
| 1 | 1 | bla |
| 2 | 1 | bla |
+----+---------------------+------+
2 rows in set (0.00 sec)
mysql> INSERT INTO checks(id,checkingaccounts_id,data) VALUES(0,2,'bla');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM checks;
+----+---------------------+------+
| id | checkingaccounts_id | data |
+----+---------------------+------+
| 1 | 1 | bla |
| 2 | 1 | bla |
| 3 | 2 | bla |
+----+---------------------+------+
3 rows in set (0.00 sec)
mysql>
Remove the auto_increment feature, try a stored procedure instead:
CREATE PROCEDURE insertChecks
(IN AccID int(9), IN data varchar(50))
BEGIN
DECLARE cid INT DEFAULT 1;
SELECT (COUNT(*) + 1) INTO cid
FROM checks
WHERE checkingaccounts_id = AccID;
INSERT INTO checks(id, checkingaccounts_id, data)
VALUES(cid, AccID, data);
END
And
call insertChecks(1,'bla');
call insertChecks(1,'bla');
call insertChecks(2,'bla');
Solution 2:
CREATE PROCEDURE insertChecks
(IN AccID int(9), IN data varchar(50))
BEGIN
INSERT INTO checks(id, checkingaccounts_id, data)
SELECT (COUNT(*) + 1), AccID, data
FROM checks
WHERE checkingaccounts_id = AccID;
END
Create a MyISAM table to create the auto_increment id only, and use a trigger to use this id for the targeted table. If there are more than one InnoDB tables that need a composite auto_incrementing primary key, add an extra primary key to the MyISAM table.
Disadvantages:
No foreign key constraints allowed on the MyISAM table, however, hopefully a trigger removes the risk.
Requires an additional table.
Advantages
Primary key valves are not reused if deleted.
Client just uses normal SQL queries and not a stored procedure.
Maybe less maintenance than a stored procedure since adding a column to a table doesn't require the trigger to be modified.
-- MySQL Script generated by MySQL Workbench
-- 07/08/16 05:12:11
-- Model: New Model Version: 1.0
SET #OLD_UNIQUE_CHECKS=##UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET #OLD_FOREIGN_KEY_CHECKS=##FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET #OLD_SQL_MODE=##SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
-- -----------------------------------------------------
-- Schema mydb
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
USE `mydb` ;
-- -----------------------------------------------------
-- Table `mydb`.`a`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`a` (
`id` INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`t1`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`t1` (
`a_id` INT NOT NULL,
`id` INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`, `a_id`),
CONSTRAINT `fk_t1_a1`
FOREIGN KEY (`a_id`)
REFERENCES `mydb`.`a` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`t2`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`t2` (
`a_id` INT NOT NULL,
`id` INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`, `a_id`),
CONSTRAINT `fk_t2_a1`
FOREIGN KEY (`a_id`)
REFERENCES `mydb`.`a` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`t3`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`t3` (
`a_id` INT NOT NULL,
`id` INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`, `a_id`),
CONSTRAINT `fk_t3_a1`
FOREIGN KEY (`a_id`)
REFERENCES `mydb`.`a` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`inc`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`inc` (
`a_id` INT NOT NULL,
`id` INT NOT NULL AUTO_INCREMENT,
`type` CHAR(4) NOT NULL,
PRIMARY KEY (`a_id`, `type`, `id`))
ENGINE = MyISAM;
SET SQL_MODE=#OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=#OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=#OLD_UNIQUE_CHECKS;
USE `mydb`;
DELIMITER $$
USE `mydb`$$
CREATE TRIGGER `t1_BINS` BEFORE INSERT ON `t1` FOR EACH ROW
BEGIN
INSERT INTO inc(a_id,type) VALUES(NEW.a_id,'t1');
SET NEW.id=LAST_INSERT_ID();
END$$
USE `mydb`$$
CREATE TRIGGER `t2_BINS` BEFORE INSERT ON `t2` FOR EACH ROW
BEGIN
INSERT INTO inc(a_id,type) VALUES(NEW.a_id,'t2');
SET NEW.id=LAST_INSERT_ID();
END$$
USE `mydb`$$
CREATE TRIGGER `t3_BINS` BEFORE INSERT ON `t3` FOR EACH ROW
BEGIN
INSERT INTO inc(a_id,type) VALUES(NEW.a_id,'t3');
SET NEW.id=LAST_INSERT_ID();
END$$
DELIMITER ;
Testing
mysql> insert into a(id) VALUES(null);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1(a_id) VALUES(1);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM t1;
+------+----+
| a_id | id |
+------+----+
| 1 | 1 |
+------+----+
1 row in set (0.00 sec)
mysql> insert into t1(a_id) VALUES(1);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1(a_id) VALUES(1);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM t1;
+------+----+
| a_id | id |
+------+----+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
+------+----+
3 rows in set (0.00 sec)
mysql> insert into t2(a_id) VALUES(1);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM t2;
+------+----+
| a_id | id |
+------+----+
| 1 | 1 |
+------+----+
1 row in set (0.00 sec)
mysql> insert into a(id) VALUES(null);
Query OK, 1 row affected (0.00 sec)
mysql> insert into a(id) VALUES(null);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1(a_id) VALUES(2);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1(a_id) VALUES(3);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1(a_id) VALUES(1);
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM t1;
+------+----+
| a_id | id |
+------+----+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
| 2 | 1 |
| 3 | 1 |
+------+----+
6 rows in set (0.00 sec)
mysql>

second auto increment in mysql

I have a mySQL (InnoDB) table:
belegID int NOT_NULL PRIMARY_KEY AUTO_INCREMENT,
docNum int NOT_NULL,
docYear date NOT_NULL,
.... -- more columns
I need the following relations:
belegID is the primary key (unique ID).
docNum is also a (unique) ID but related to the year. Each year starts by 1.
How can I solve this on mySQL side and how can I get the next docNum (ID related to the year)?
Thank you in advance.
You can use triggers to resolve your issue. Here is simple example (don't forget to rename schema and table if you'll try to use that):
DELIMITER //
CREATE TRIGGER fillDocNumber BEFORE INSERT ON test.t
FOR EACH ROW
BEGIN
SET #maxNum = (SELECT MAX(docNum) FROM test.t WHERE YEAR(docYear)=YEAR(NEW.docYear));
IF #maxNum IS NULL THEN
SET NEW.docNum=1;
ELSE
SET NEW.docNum=#maxNum+1;
END IF;
END;//
DELIMITER ;
Let's assume we have table:
CREATE TABLE `t` (
`belegID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`docNum` int(11) unsigned DEFAULT NULL,
`docYear` date NOT NULL,
PRIMARY KEY (`belegID`)
) ENGINE=InnoDB;
After creating our trigger we'll populate it with some data:
mysql> insert into t (docYear) values ('2013-04-06');
Query OK, 1 row affected (0.13 sec)
mysql> insert into t (docYear) values ('2012-02-18');
Query OK, 1 row affected (0.05 sec)
mysql> insert into t (docYear) values ('2013-12-11');
Query OK, 1 row affected (0.02 sec)
mysql> insert into t (docYear) values ('2014-10-30');
Query OK, 1 row affected (0.07 sec)
mysql> insert into t (docYear) values ('2014-01-03');
Query OK, 1 row affected (0.06 sec)
and now it's our result:
mysql> select * from t;
+---------+--------+------------+
| belegID | docNum | docYear |
+---------+--------+------------+
| 1 | 1 | 2013-04-06 |
| 2 | 1 | 2012-02-18 |
| 3 | 2 | 2013-12-11 |
| 4 | 1 | 2014-10-30 |
| 5 | 2 | 2014-01-03 |
+---------+--------+------------+
5 rows in set (0.00 sec)
Quite as expected.
Hint: rename field docYear, it's confusing. Correct name would be docDate (or store year in it and document's date in separate field - in fact, that will increase performance since then you'll be able to create index by it and get rid of YEAR() function in calculating MAX within trigger - and so index will be used).