MySQL Trigger doesn't know default value - mysql

I use this trigger
delimiter ||
create TRIGGER column_a_to_default
BEFORE INSERT ON `property`
FOR EACH ROW
BEGIN
IF NEW.primary_image = '' THEN
SET NEW.primary_image = default(NEW.primary_image);
END IF;
END;
||
delimiter ;
If I insert into the table the trigger throws an error:
Field 'primary_image' doesn't have a default value.
But it does!
What is wrong here? It seems like the trigger isn't aware of default values!
EDIT
Table Create script
CREATE TABLE IF NOT EXISTS `property` (
`id` varchar(10) NOT NULL,
`images` text NOT NULL,
`primary_image` varchar(100) NOT NULL DEFAULT '../no-image.png',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Doesn't default(property.primary_image) work?
(Getting the default of the Real table, not the NEW holding-table)

Somehow it does not work.
Try this workaround -
IF NEW.primary_image = '' THEN
SELECT COLUMN_DEFAULT INTO #def
FROM information_schema.COLUMNS
WHERE
table_schema = 'database_name'
AND table_name = 'property'
AND column_name = 'primary_image';
SET NEW.primary_image = #def;
END IF;

Related

MySQL trigger - Adding from a separate table

I have two tables:
CREATE TABLE `class` (
`id` int(11) NOT NULL,
`class_no` int(11) NOT NULL,
`class_title` varchar(11) NOT NULL,
`no_of_students` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `enrolment` (
`id` int(11) NOT NULL,
`ssn` varchar(11) NOT NULL,
`class_no` int(11) NOT NULL,
`grade` varchar(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
What I am trying to do is when someone enters into 'Enrolment', if the class number entered matches an entry in 'Class', e.g. class number 2 - then i want what is typed into grade on 'Enrolment' (i.e 5) to add to whatever is already in number of students (Say if it's 10). In this case, the number of students would then say 15. This is the current trigger i have, however is not adding:
DELIMITER $$
CREATE TRIGGER `after_insert_add_one` AFTER INSERT ON `enrolment` FOR EACH ROW UPDATE class
SET class.no_of_students = class.no_of_students + enrolment.grade WHERE class_no = NEW.class_no
$$
DELIMITER ;
If anyone knows i'd be grateful for the help.
You must use the NEW key instead of the name of table enrolment, try this
CREATE TRIGGER `after_insert_enrolment` AFTER INSERT ON `enrolment`
FOR EACH ROW BEGIN
UPDATE class c
SET
c.no_of_students = c.no_of_students + NEW.grade
WHERE c.class_no = NEW.class_no;
END
You’re not making changes with SET class.no_of_students = class.no_of_students + enrolment.grade if you’re not using enrolment.class_no to compare using where clause. Update it with NEW in place of enrolment if you’re using it:
DELIMITER $
CREATE TRIGGER `after_insert_add_one` AFTER INSERT ON `enrolment` FOR EACH ROW UPDATE class
SET class.no_of_students = class.no_of_students + NEW.grade WHERE class_no = NEW.class_no
$
DELIMITER ;

Mysql trigger update field on t2 on update t1 column

I've 2 tables (t1,t2) on my test db.
CREATE TABLE IF NOT EXISTS `t1` (
`name` varchar(10) NOT NULL,
`code` varchar(10) NOT NULL,
`end_date` varchar(8) NOT NULL
);
CREATE TABLE IF NOT EXISTS `t2` (
`date` varchar(8) NOT NULL
);
I'd like to create a trigger for update t2.date (with t1.end_date value) when update t1.end_date.
I've tried this way but with no success (Variable 'OLD' is not a variable component (can't be used as XXXX.variable_name)).
CREATE TRIGGER update_date BEFORE UPDATE ON t1 FOR EACH ROW
IF NOT (t1.NEW.end_date <=> t1.OLD.end_date) THEN
SET t2.OLD.date = t2.NEW.end_date;
END IF
How can I do this? Thanks
delimiter |
CREATE TRIGGER update_date AFTER UPDATE ON t1
FOR EACH ROW BEGIN
IF NOT (NEW.end_date <=> OLD.end_date) THEN
update t2
SET `date` = NEW.end_date;
END IF;
END
|
delimiter ;
And please don't use strings to store dates. Use the date data type!

error while calling stored procedure: You are using safe update

I am trying to call a stored procedure, but I am getting : Error Code: 1175 You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
Here is the table:
CREATE TABLE `SystemSetting` (
`SettingName` varchar(45) NOT NULL,
`SettingValue` varchar(45) NOT NULL,
`Deleted` bit(1) NOT NULL DEFAULT b'0',
PRIMARY KEY (`SettingName`),
KEY `PK_SystemSetting` (`SettingName`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
and the procedure:
DELIMITER $$
CREATE PROCEDURE `SystemSettingCommit` (IN p_SettingName varchar(45), IN p_SettingValue varchar(45), OUT p_Status varchar(55))
BEGIN
SET p_Status = '00000';
IF (p_SettingValue IS NULL) OR (RTRIM(LTRIM(p_SettingValue)) = '') THEN
SET p_Status = `StatusConcat`(p_Status, '10016');
END IF;
IF (p_SettingName IS NULL) OR (RTRIM(LTRIM(p_SettingName)) = '') THEN
SET p_Status = `StatusConcat`(p_Status, '10017');
END IF;
IF (p_Status = '00000') THEN
IF ((SELECT COUNT(`SettingName`) FROM `SystemSetting` WHERE (`SettingName` = p_SettingName)) > 0) THEN
UPDATE `SystemSetting` SET `SettingValue` = p_SettingValue WHERE (`SettingName` = p_SettingName);
ELSE
INSERT INTO `SystemSetting` (`SettingName`, `SettingValue`) VALUES (p_SettingName, p_SettingValue);
END IF;
END IF;
END$$
DELIMITER;
and this is how I call it:
CALL `SystemSettingCommit` ('Setting1', 'Value1', #Status);
Try this:
SET SQL_SAFE_UPDATES=0;
Or follow this in workbench:
Go to Edit --> Preferences
Click "SQL Queries" tab and uncheck "Safe Updates" check box
Query --> Reconnect to Server
Now execute your sql query

Generate auto incremented id for BPM application

Within a BPM web application, I have a field for an invoice # on a particular page but I need for it to be auto generated every time a user attaches an invoice and views that page. That number must be unique and preferably auto-incremented. A value for the invoice # field can be displayed by querying from a table from an external MYSQL database. So every time a user lands on that particular page, a SELECT query statement can be fired.
On MYSQL end, how would I set this up? So basically, I would like to setup a query for that invoice # field where it will for run a query for example,
SELECT invoice_num FROM invoice_generator
and every time this query runs, it would return the next incremented number.
You can use mysql trigger concept here....
I have added one example here...
It will be very usefull for u (see this link also :http://www.freemindsystems.com/mysql-triggers-a-practical-example/)
CREATE TABLE `products` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL DEFAULT '',
`price` int(20) NOT NULL DEFAULT '0',
`other` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `products_name_idx` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `freetags` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tag` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `freetagged_objects` (
`tag_id` int(20) NOT NULL DEFAULT '0',
`object_id` int(20) NOT NULL DEFAULT '0',
`tagged_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`module` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`tag_id`, `object_id`),
KEY `freetagged_objects_tag_id_object_id_idx` (`tag_id`, `object_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
INSERT_PRODUCTS_TAGS
DELIMITER ||
DROP TRIGGER IF EXISTS insert_products_tags;
||
DELIMITER ##
CREATE TRIGGER insert_products_tags AFTER INSERT ON products
FOR EACH ROW
BEGIN
DECLARE current_id integer;
DECLARE tag_id integer;
DECLARE next integer;
DECLARE tag_field varchar(255);
DECLARE next_sep integer;
DECLARE current_tag varchar(255);
DECLARE right_tag varchar(255);
-- We use the field other as comma-separated tag_field
SET tag_field = NEW.other;
-- Check for empty tags
IF (CHAR_LENGTH(tag_field) <> 0) THEN
-- Loop until no more ocurrencies
set next = 1;
WHILE next = 1 DO
-- Find possition of the next ","
SELECT INSTR(tag_field, ',') INTO next_sep;
IF (next_sep > 0) THEN
SELECT SUBSTR(tag_field, 1, next_sep - 1) INTO current_tag;
SELECT SUBSTR(tag_field, next_sep + 1, CHAR_LENGTH(tag_field)) INTO right_tag;
set tag_field = right_tag;
ELSE
set next = 0;
set current_tag = tag_field;
END IF;
-- Drop spaces between comas
SELECT TRIM(current_tag) INTO current_tag;
-- Insert the tag if not already present
IF (NOT EXISTS (SELECT tag FROM freetags WHERE tag = current_tag)) THEN
-- Insert the tag
INSERT INTO freetags (tag) values (current_tag);
SELECT LAST_INSERT_ID() INTO tag_id;
ELSE
-- Or get the id
SELECT id FROM freetags WHERE tag = current_tag INTO tag_id;
END IF;
-- Link the object tagged with the tag
INSERT INTO freetagged_objects
(tag_id, object_id, module)
values
(tag_id, NEW.id, 'products');
END WHILE;
END IF;
END;
##
Now If you execute an insert on products table:
INSERT INTO PRODUCTS
(name, price, other)
values
("product1", 2, "tag1, tag2,tag3 , tag 4");

Change auto increment starting number?

In MySQL, I have a table, and I want to set the auto_increment value to 5 instead of 1. Is this possible and what query statement does this?
You can use ALTER TABLE to change the auto_increment initial value:
ALTER TABLE tbl AUTO_INCREMENT = 5;
See the MySQL reference for more details.
Yes, you can use the ALTER TABLE t AUTO_INCREMENT = 42 statement. However, you need to be aware that this will cause the rebuilding of your entire table, at least with InnoDB and certain MySQL versions. If you have an already existing dataset with millions of rows, it could take a very long time to complete.
In my experience, it's better to do the following:
BEGIN WORK;
-- You may also need to add other mandatory columns and values
INSERT INTO t (id) VALUES (42);
ROLLBACK;
In this way, even if you're rolling back the transaction, MySQL will keep the auto-increment value, and the change will be applied instantly.
You can verify this by issuing a SHOW CREATE TABLE t statement. You should see:
> SHOW CREATE TABLE t \G
*************************** 1. row ***************************
Table: t
Create Table: CREATE TABLE `t` (
...
) ENGINE=InnoDB AUTO_INCREMENT=43 ...
How to auto increment by one, starting at 10 in MySQL:
create table foobar(
id INT PRIMARY KEY AUTO_INCREMENT,
moobar VARCHAR(500)
);
ALTER TABLE foobar AUTO_INCREMENT=10;
INSERT INTO foobar(moobar) values ("abc");
INSERT INTO foobar(moobar) values ("def");
INSERT INTO foobar(moobar) values ("xyz");
select * from foobar;
'10', 'abc'
'11', 'def'
'12', 'xyz'
This auto increments the id column by one starting at 10.
Auto increment in MySQL by 5, starting at 10:
drop table foobar
create table foobar(
id INT PRIMARY KEY AUTO_INCREMENT,
moobar VARCHAR(500)
);
SET ##auto_increment_increment=5;
ALTER TABLE foobar AUTO_INCREMENT=10;
INSERT INTO foobar(moobar) values ("abc");
INSERT INTO foobar(moobar) values ("def");
INSERT INTO foobar(moobar) values ("xyz");
select * from foobar;
'11', 'abc'
'16', 'def'
'21', 'xyz'
This auto increments the id column by 5 each time, starting at 10.
You can also do it using phpmyadmin. Just select the table than go to actions. And change the Auto increment below table options. Don't forget to click on start
Procedure to auto fix AUTO_INCREMENT value of table
DROP PROCEDURE IF EXISTS update_auto_increment;
DELIMITER //
CREATE PROCEDURE update_auto_increment (_table VARCHAR(64))
BEGIN
DECLARE _max_stmt VARCHAR(1024);
DECLARE _stmt VARCHAR(1024);
SET #inc := 0;
SET #MAX_SQL := CONCAT('SELECT IFNULL(MAX(`id`), 0) + 1 INTO #inc FROM ', _table);
PREPARE _max_stmt FROM #MAX_SQL;
EXECUTE _max_stmt;
DEALLOCATE PREPARE _max_stmt;
SET #SQL := CONCAT('ALTER TABLE ', _table, ' AUTO_INCREMENT = ', #inc);
PREPARE _stmt FROM #SQL;
EXECUTE _stmt;
DEALLOCATE PREPARE _stmt;
END//
DELIMITER ;
CALL update_auto_increment('your_table_name')
If you need this procedure for variable fieldnames instead of id this might be helpful:
DROP PROCEDURE IF EXISTS update_auto_increment;
DELIMITER //
CREATE PROCEDURE update_auto_increment (_table VARCHAR(128), _fieldname VARCHAR(128))
BEGIN
DECLARE _max_stmt VARCHAR(1024);
DECLARE _stmt VARCHAR(1024);
SET #inc := 0;
SET #MAX_SQL := CONCAT('SELECT IFNULL(MAX(',_fieldname,'), 0) + 1 INTO #inc FROM ', _table);
PREPARE _max_stmt FROM #MAX_SQL;
EXECUTE _max_stmt;
DEALLOCATE PREPARE _max_stmt;
SET #SQL := CONCAT('ALTER TABLE ', _table, ' AUTO_INCREMENT = ', #inc);
PREPARE _stmt FROM #SQL;
EXECUTE _stmt;
DEALLOCATE PREPARE _stmt;
END //
DELIMITER ;
CALL update_auto_increment('your_table_name', 'autoincrement_fieldname');
just export the table with data ..
then copy its sql like
CREATE TABLE IF NOT EXISTS `employees` (
`emp_badgenumber` int(20) NOT NULL AUTO_INCREMENT,
`emp_fullname` varchar(100) NOT NULL,
`emp_father_name` varchar(30) NOT NULL,
`emp_mobile` varchar(20) DEFAULT NULL,
`emp_cnic` varchar(20) DEFAULT NULL,
`emp_gender` varchar(10) NOT NULL,
`emp_is_deleted` tinyint(4) DEFAULT '0',
`emp_registration_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`emp_overtime_allowed` tinyint(4) DEFAULT '1',
PRIMARY KEY (`emp_badgenumber`),
UNIQUE KEY `bagdenumber` (`emp_badgenumber`),
KEY `emp_badgenumber` (`emp_badgenumber`),
KEY `emp_badgenumber_2` (`emp_badgenumber`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=111121326 ;
now change auto increment value and execute sql.