i have a problem in after insert trigger. when i am inserting the data in the table it should automatically update the date and it should be the current date. but when i am executing the following query it is not working properly in my table.
first i created a table:
DROP TABLE IF EXISTS `ignite`.`products`;
CREATE TABLE `ignite`.`products`(
`products_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`products_model` varchar(30) NOT NULL,
`model_hash` bigint(20) unsigned NOT NULL,
`Product_name` varchar(45) NOT NULL,
`created` datetime NOT NULL,
PRIMARY KEY (`products_id`)
) ENGINE=MyISAM AUTO_INCREMENT=977 DEFAULT CHARSET=latin1;
Then i created this trigger:
use ignite;
CREATE TRIGGER created_date BEFORE INSERT ON products
FOR EACH ROW
SET NEW.created = NOW();
but when i am inserting the data in this table:
use ignite;
INSERT INTO products
(products_id, products_model, model_hash, Product_name)
values
(123, "456645", 457567, "awetert");
This is showing the following error:
field 'created' does not have default value. error-1364
It's because on your INSERT statement does not include the created values. You need to include it for example with zero datetime value:
INSERT INTO products
(products_id, products_model, model_hash, Product_name, created)
values
(123, "456645", 457567, "awetert", "0000-00-00 00:00:00");
Related
I'm new to triggers in MySQL, so sorry for any question that seems "really easy".
I have two tables: orders and orders_log
orders:
order_id
(...)
product_id
(...)
201
(...)
103
(...)
oders_log:
log_id
action
table_name
action_time
product_id
NULL
NULL
NULL
NULL
NULL
I want to create a trigger that when we INSERT a new row into "orders" table, it will generate a new row into orders_log with the log_id = 1...2..3... etc; and product_id = to product_id in table "orders". So that the orders_log would look like this:
log_id
action
table_name
action_time
product_id
1
insert
orders
"now()"
103
I'm trying to do this code:
DROP TRIGGER IF EXISTS addrowlog;
DELIMITER $$
CREATE TRIGGER addrowlog
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
insert into orders_log (`log_id`, `action`, `table_name`, `action_time`, `product_id`)
VALUES (NEW.log_id, 'insert', 'orders', NOW(), NEW.product_id);
END$$
DELIMITER;
But is gaves this error: Error Code: 1054. Unknow column 'log_id' in 'NEW.
And even when i just do this code:
DROP TRIGGER IF EXISTS addrowlog;
DELIMITER $$
CREATE TRIGGER addrowlog
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
insert into orders_log (`log_id`, `action`, `table_name`, `action_time`, `product_id`)
VALUES (log_id, 'insert', 'orders', NOW(), product_id);
END$$
DELIMITER;
When i try to add a row into 'orders' it will give me error "Cannot add or update a child row: a foreign key constraint fails".
Can someone help me?
*EDIT:
Creation of the log table:
CREATE TABLE `orders_log` (
`log_id` INTEGER NOT NULL,
`action` VARCHAR(255) DEFAULT NULL,
`table_name` VARCHAR(255) DEFAULT NULL,
`action_time` TIME DEFAULT NULL,
`product_id` INTEGER NOT NULL,
PRIMARY KEY (`log_id`)
);
(trigger created in the middle)
plus
ALTER TABLE `orders_log`
ADD CONSTRAINT `fk_orders_log_3`
FOREIGN KEY (`product_id`)
REFERENCES `product` (`product_id`)
ON DELETE RESTRICT
ON UPDATE CASCADE;
```*
After adding the auto_increment, you can remove the log_id from your insert or add NULL as value
CREATE TABLe orders (product_id int)
CREATE TABLE `orders_log` (
`log_id` INTEGER NOT NULL AUTO_INCREMENT,
`action` VARCHAR(255) DEFAULT NULL,
`table_name` VARCHAR(255) DEFAULT NULL,
`action_time` TIME DEFAULT NULL,
`product_id` INTEGER NOT NULL,
PRIMARY KEY (`log_id`)
);
CREATE TRIGGER addrowlog
AFTER INSERT ON orders
FOR EACH ROW
BEGIN
insert into orders_log ( `action`, `table_name`, `action_time`, `product_id`)
VALUES ( 'insert', 'orders', NOW(), new.product_id);
END
INSERt INTO orders VALUEs(1)
SELECT * FROM orders_log
log_id
action
table_name
action_time
product_id
1
insert
orders
12:10:43
1
fiddle
as I'm working on a small app for managing metadata and I was wondering if it is possible to insert row in another table if conditions are met.
Let me follow with example: So, let's say we have table ispu_plan
CREATE TABLE `ispu_plan` (
`id` int(11) NOT NULL,
`id_jls` int(11) NOT NULL,
`id_razina_plan` int(11) NOT NULL,
`id_revizija` int(11) NOT NULL,
`naziv_plan` varchar(150) NOT NULL,
`ispu_naziv` varchar(100) NOT NULL,
`id_mjerilo` int(11) NOT NULL,
`datum_donosenja_plana` date DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
and as I'm updating table ispu_plan I want to update another table (e.g. ispu_plan_updated) if certain conditions are met in ispu_plan with same rows from table ispu_plan
Using this query:
SELECT * FROM ispu_plan WHERE datum_donosenja_plana BETWEEN '2014-01-01' AND CURDATE()
I want to insert row in table ispu_plan_updated. Is something like this possible and can I insert rows in ispu_plan_updated using views?
Thank you
You can use a trigger to achieve that:
DROP TRIGGER IF EXISTS ispu_plan_trigger;
DELIMITER |
CREATE TRIGGER ispu_plan_trigger AFTER UPDATE ON ispu_plan
FOR EACH ROW BEGIN
-- example condition with update:
IF NEW.datum_donosenja_plana >= '2017-01-01' THEN
UPDATE ispu_plan_updated SET naziv_plan = 'some_value' WHERE id = NEW.id
LIMIT 1;
END IF;
END;
DELIMITER ;
I have a large table with 110M rows. I would like to copy some of the fields into a new table and here is a rough idea of how I am trying to do:
DECLARE l_seenChangesTo DATETIME DEFAULT '1970-01-01 01:01:01';
DECLARE l_migrationStartTime DATETIME;
SELECT NOW() into l_migrationStartTime;
-- See if we've run this migration before and if so, pick up from where we left off...
IF EXISTS(SELECT seenChangesTo FROM migration_status WHERE client_user = CONCAT('this-migration-script-', user())) THEN
SELECT seenChangesTo FROM migration_status WHERE client_user = CONCAT('this-migration-script-', user()) INTO l_seenChangesTo;
SELECT NOW() as LogTime, CONCAT('Picking up from where we left off: ', l_seenChangesTo) as MigrationStatus;
END IF;
INSERT IGNORE INTO newTable
(field1, field2, lastModified)
SELECT o.column1 AS field1,
o.column2 AS field2,
o.lastModified
FROM oldTable o
WHERE
o.lastModified >= l_seenChangesTo AND
o.lastModified <= l_migrationStartTime;
INSERT INTO migration_status (client_user,seenChangesTo)
VALUES (CONCAT('this-migration-script-', user()), l_migrationStartTime)
ON DUPLICATE KEY UPDATE seenChangesTo=l_migrationStartTime;
Context:
CREATE TABLE IF NOT EXISTS `newTable` (
`field1` varchar(255) NOT NULL,
`field2` tinyint unsigned NOT NULL,
`lastModified` datetime NOT NULL,
PRIMARY KEY (`field1`, `field2`),
KEY `ix_field1` (`field1`),
KEY `ix_lastModified` (`lastModified`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `oldTable` (
`column1` varchar(255) NOT NULL,
`column2` tinyint unsigned NOT NULL,
`lastModified` datetime NOT NULL,
PRIMARY KEY (`column1`, `column2`),
KEY `ix_column1` (`column1`),
KEY `ix_lastModified` (`lastModified`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `migration_status` (
`client_user` char(64) NOT NULL,
`seenChangesTo` char(128) NOT NULL,
PRIMARY KEY (`client_user`)
);
Note: I have a few more columns in oldTable. Both oldTable and newTable are in same DB schema using mysql.
What's the general strategy when copying a very table? Should I perform this migration in an iterative manner by copy say 50,000 rows at time.
The insert speed doing a migration like this iteratively is going to be dreadfully slow. Why not SELECT oldTable INTO OUTFILE, then LOAD DATA INFILE ?
There is a table:
CREATE TABLE `mytable` (
`user_id` INT(10) UNSIGNED NOT NULL,
`thing_id` VARCHAR(100) NOT NULL DEFAULT '',
`lock_date` DATETIME NOT NULL,
`lock_id` VARCHAR(36) NOT NULL,
PRIMARY KEY (`user_id`,`thing_id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
and some values there:
INSERT INTO mytable(user_id,thing_id,lock_date,lock_id)
VALUES
(51082,'299ac9ff-2b2b-102d-8ff6-f64c971398c3','2012-03-16 00:39:12','ec7b2008-6ede-11e1-aac2-5924aae99221'),
(108325,'299ac9ff-2b2b-102d-8ff6-f64c971398c3','2013-02-05 19:30:03','7c6de986-6edd-11e1-aac2-5924aae99221'),
(108325,'d90b354d-4b5f-11e0-9959-47117d41cf4b','2012-03-16 00:47:41','1c243032-6ee0-11e1-aac2-5924aae99221');
I want to delegate all records of user_id = 108325 to user_id = 51082, and if both users have an equal thing_id field, leave the newer one only (lock_date1 > lock_date2), so that I have following result:
51082,'299ac9ff-2b2b-102d-8ff6-f64c971398c3','2013-02-05 19:30:03','7c6de986-6edd-11e1-aac2-5924aae99221'
108325,'d90b354d-4b5f-11e0-9959-47117d41cf4b','2012-03-16 00:47:41','1c243032-6ee0-11e1-aac2-5924aae99221'
Note that 51082 now has a newer record: lock_date = '2013-02-05 19:30:03' instead of '2012-03-16 00:39:12'.
So, how can I update a row, and on duplicate key leave the newer one (by some particular field)?
Thanks!
INSERT INTO
mytable(user_id,thing_id,lock_date,lock_id)
VALUES
(51082,'299ac9ff-2b2b-102d-8ff6-f64c971398c3','2012-03-16 00:39:12','ec7b2008-6ede-11e1-aac2-5924aae99221'),
(108325,'299ac9ff-2b2b-102d-8ff6-f64c971398c3','2013-02-05 19:30:03','7c6de986-6edd-11e1-aac2-5924aae99221'),
(108325,'d90b354d-4b5f-11e0-9959-47117d41cf4b','2012-03-16 00:47:41','1c243032-6ee0-11e1-aac2-5924aae99221')
ON DUPLICATE KEY UPDATE SET
user_id = VALUES(user_id),
lock_date = VALUES(lock_date),
lock_id = VALUES(lock_id)
Table: items
Create Table:
CREATE TABLE `items` (
`ite_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`itemName` varchar(40) DEFAULT NULL,
`itemNumber` int(10) unsigned NOT NULL,
PRIMARY KEY (`ite_id`),
UNIQUE KEY `itemName` (`itemName`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
delimiter |
create trigger item_beforeinsert before insert on items
for each row begin
if new.itemNumber < 50 then
set new.ite_id = null;
end if;
end;
|
now the following command doesn't cause a trigger
insert items( itemname, itemnumber) values ( 'xyz', 1 );
any help would be very much appreciated, thanks!
Your ite_ID is not null and you want to set it null with your trigger, beside that it's auto increment, so you wont be able to 'control' all the values to assign to that field, I.E it wont overwrite values
It'd be
insert INTO items( itemname, itemnumber) values ( 'xyz', 1 );
also, since you have set ite_id as NOT NULL, you can't use a set new.ite_id = null;
For auto incremented primary key fields you can pass NULL value while inserting. MySQL automatically assigns auto generated value. It is not an error setting up NULL to it BEFORE insert. And hence trigger didn't fire an error.
Example:
insert into items( ite_id, ... ) values ( null, ... );
The above statement is valid and works, since ite_id field is primary key with auto increment.