Trigger+procedure issue - mysql

As the title says, I have an issue with the trigger + procedure.
What I'm trying to do it's a procedure + trigger that creates an email with the name and surnames only if when I'm trying to insert a student data w/o an email.
Basically where am stuck is, the code makes the fusion of name and surname and creates the email, but how do I place it before it inserts inside the table?
Best regards,
Engineer
Here's the code I have made:
use alumnesTriggers;
drop procedure if exists ex2;
delimiter //
create procedure ex2 (in nom varchar(50), in cognom1 varchar(50),
in cognom2 varchar(50), in domini varchar(50), out email varchar(50))
begin
set email := concat(nom,cognom1,cognom2,'#',domini,'.com');
#set #email := email;
#UPDATE alumnesEmail as ae SET ae.email = #email WHERE nom = #nom;
end //
delimiter ;
drop trigger if exists ex2_2_trigger;
DELIMITER $$
CREATE TRIGGER ex2_2_trigger before insert on alumnesEmail for each row begin
set #mail := new.email;
#if #mail := null or #mail='' then
set #id := new.id;
set #nom := new.nom;
set #cognom1 := new.cognom1;
set #cognom2 := new.cognom2;
call ex2(#nom,#cognom1,#cognom2,'gmail',#email);
UPDATE alumnesEmail SET new.email = #email;
#end if;
END $$
DELIMITER ;
INSERT INTO `alumnesEmail` (`id`, `nom`, `cognom1`, `cognom2`, `email`)
VALUES (80, 'a', 'a', 'a',null);
select * from alumnesEmail where id = 80;
select #email;
select * from alumnesEmail ;

but how do I place it before it inserts inside the table?
In a before trigger, you just set new.email to the target value. This modifies the value that is about to be written to the database.
Also, the procedure seems superfluous here.
The following code should do just what you want:
delimiter $$
create trigger ex2_2_trigger
before insert on alumnesemail
for each row
begin
if new.email is null or new.email = '' then
set new.email = concat(new.nom, new.cognom1, new.cognom2, '#gmail.com');
end if;
end $$
delimiter ;

Related

Automatically set the value of a column from a function or query

I have a MariaDB database and I have table userInfo which has a column of ipAddress and country. I want to have another column named country and automatically get the country from the ipAddress and insert it in the country column. I already imported GeoIPLite2 and already have a SQL Query but I dont know how to use make mariadb do it instead of doing it on my code.
SELECT a.country_name
FROM geoipcountries a, geoipblocks b
WHERE INET_ATON('1.2.3.4') BETWEEN network_start_integer AND network_last_integer
AND b.geoname_id = a.geoname_id
This query give me the country name.
I want the MySQL to set the value of country column in userInfo table from the output of the query above.
I already wrote this function as well:
DELIMITER $$
CREATE FUNCTION getIpCountry(ip varchar(15)) RETURNS varchar(64)
BEGIN
declare result varchar(64);
select SQL_CACHE a.country_name into result FROM geoipcountries a, geoipblocks b WHERE INET_ATON(ip) BETWEEN network_start_integer AND network_last_integer AND b.geoname_id = a.geoname_id;
if (result is null) or (result = '') then
set result := 'unknown';
end if;
return result;
END$$
DELIMITER ;
IF you want to change all county names in one goal
Do a
UPDATE userInfo SET `country`= getIpCountry(`ipAddress `);
But today we use join and not comma separated tables
DELIMITER $$
CREATE FUNCTION getIpCountry(ip varchar(15)) RETURNS varchar(64)
BEGIN
declare result varchar(64);
SELECT
a.country_name
INTO result
FROM
geoipcountries a
INNER JOIN
geoipblocks b ON b.geoname_id = a.geoname_id
WHERE
INET_ATON(ip) BETWEEN network_start_integer AND network_last_integer;
if (result is null) or (result = '') then
set result := 'unknown';
end if;
return result;
END$$
DELIMITER ;
To d that automatically you need a BEFORE INSERT TRIGGER
DELIMITER $$
CREATE TRIGGER before_userInfo_insert
BEFORE INSERT
ON userInfo FOR EACH ROW
BEGIN
SET NEW.`country`= getIpCountry(NEW.`ipAddress `);
END $$
DELIMITER ;
and a BEFORE UPDATE TRIGGER
CREATE TRIGGER before_userInfo_update
BEFORE UPDATE
ON userInfo FOR EACH ROW
BEGIN
SET NEW.`country`= getIpCountry(NEW.`ipAddress `);
END $$
DELIMITER ;
Considering you table is userInfo and you want your country column to auto populate based on ipAddress. Use CREATE TRIGGER
DELIMITER $$
CREATE TRIGGER `userinfo_before_insert` BEFORE INSERT ON `userInfo` FOR EACH ROW BEGIN
SET NEW.country = getIpCountry(NEW.ipAddress);
END $$
Note: If ipAddress can be null, so make sure you handle that in your function getIpCountry function.
Same you can on on update event too.
DELIMITER $$
CREATE TRIGGER `userinfo_before_update` BEFORE UPDATE ON `userInfo` FOR EACH ROW BEGIN
SET NEW.country = getIpCountry(NEW.ipAddress);
END $$
Now just skip country column from both INSERT and UPDATE query and make sure to include ipAddress. It would be like as follow
INSERT INTO userInfo(user_id, ipAddress) VALUES (1, '172.16.6.20');
UPDATE userInfo SET ipAddress = '172.16.6.20' WHERE user_id = 1;

how to declare variable phpmyadmin mysql triggers properly?

I have a database where whenever residential address update in user table I want it to store in history table of user. For that I'm trying to write triggers but failing miserably in phpmyadmin. Also it's not giving me proper reason why so I can correct it. This is what I have done so far.
DROP TRIGGER IF EXISTS `record_history`;
CREATE TRIGGER `record_history` AFTER UPDATE ON `s_user`
FOR EACH ROW
BEGIN
DECLARE date_current datetime;
DECLARE residential_address varchar(1000);
SET #date_current = NOW();
SET #residential_address = NEW.residential_address;
IF (#residential_address <> OLD.residential_address AND #residential_address != "" AND #residential_address IS NOT NULL) THEN
INSERT INTO history_residential_address (`s_u_id`, `residential_address`, `status`, `date_added`, `date_updated`) VALUES
(OLD.s_u_id, #residential_address, 1, #date_current, #date_current);
END IF;
END;
delimiter ;
A cleaner version of your code
DROP TRIGGER IF EXISTS `record_history`;
delimiter $$
CREATE TRIGGER `record_history` AFTER UPDATE ON `s_user`
FOR EACH ROW
BEGIN
IF (new.residential_address <> OLD.residential_address AND new.residential_address <> "" AND new.residential_address IS NOT NULL) THEN
INSERT INTO history_residential_address (`s_u_id`, `residential_address`, `status`, `date_added`, `date_updated`) VALUES
(OLD.s_u_id, new.residential_address, 1, now(), now());
END IF;
END $$
delimiter ;
If you are still having problems please add sample data from s_user as text to the question.

Mysql trigger to update empty field with condition

I have a MySQL table , look like this
t id lang title
1 7 en_UK my_title
1 7 kh_KH
I want write a trigger that update title to my_title with the same id is 7
Result
t id lang title
1 7 en_UK my_title
1 7 kh_KH my_title
From my understanding.
DELIMITER $$
CREATE TRIGGER upd_title BEFORE UPDATE ON `term`
FOR EACH ROW BEGIN
IF (NEW.title IS NULL OR NEW.title= '') THEN
SET NEW.title= ??? ;
END IF;
END$$
DELIMITER ;
[UPDATE1]->not works (trigger not being created)
DELIMITER $$
DROP TRIGGER IF EXISTS `update_category_after_insert`
CREATE TRIGGER `update_category` AFTER INSERT ON `categories`
FOR EACH ROW BEGIN
DECLARE loc_title text;
IF (NEW.libelle_categorie IS NULL OR NEW.libelle_categorie= '') THEN
select libelle_categorie into loc_title from categories where NEW.num_noeud= num_noeud and langue = 'en_UK';
SET NEW.libelle_categorie = loc_title;
END IF;
END
DELIMITER ;
[UPDATE2]
DELIMITER $$
CREATE TRIGGER ``update_category_after_insert`` BEFORE INSERT ON `categories`
FOR EACH ROW BEGIN
DECLARE loc_title text;
IF (NEW.libelle_categorie IS NULL OR NEW.libelle_categorie= '') THEN
select libelle_categorie into loc_title from categories where NEW.num_noeud= num_noeud and langue = 'en_UK';
SET NEW.libelle_categorie = loc_title;
END IF;
END
DELIMITER ;
Finally , I found the good solution for my case
UPDATE categories c INNER JOIN categories c2 ON (
c.num_noeud = c2.num_noeud
) SET c.libelle_categorie = c2.`libelle_categorie`
Can you clarify?
Are you trying to pull the value from the title column in the 'en_UK' row that exists when you insert an new row with the same id that HAS the title column not entered?
okay
CREATE TRIGGER upd_title BEFORE UPDATE ON `term`
FOR EACH ROW BEGIN
DECLARE loc_title VARCHAR(20);
IF (NEW.title IS NULL OR NEW.title= '') THEN
select title into loc_title from term where NEW.id = id and lang = 'en_UK';
SET NEW.title= loc_title;
END IF;
END
This should do the trick.
This was my trigger def:
CREATE DEFINER = CURRENT_USER TRIGGER `therinks`.`glreturndata_BEFORE_UPDATE` BEFORE UPDATE ON `glreturndata` FOR EACH ROW
BEGIN
DECLARE myVal VARCHAR(20);
if NEW.DESCRIPTION IS NULL or new.description = '' THEN
SELECT min(description) into myVal from glreturndata where category = NEW.category and new.idglreturndata <> idglreturndata;
Set NEW.DESCRIPTION = myval;
end if;
END
It seems that you can't do all this in a trigger. According to the documentation:
Within a stored function or trigger, it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
According to this answer, it seems that you should:
create a stored procedure, that inserts into/Updates the target table, then updates the other row(s), all in a transaction.
With a stored proc you'll manually commit the changes (insert and update). I haven't done this in MySQL, but this post looks like a good example.

Executing query in MySQL Trigger not working

I have two table 'testing1' with fields 'firstname' and 'lastname'. Another table 'testing2' with field 'firstname'.
So the trigger checks first whether the 'NEW.firstname' exists in 'testing2' table or not. If it does then it doesn't execute the INSERT query but if it doesn't exist then the INSERT query is executed and 'NEW.firstname' is added in 'testing2' table.
Here's the trigger that i created ... but I'm getting error in the IF loop ...
DELIMITER $$;
CREATE TRIGGER testRef AFTER INSERT ON testing1
FOR EACH ROW
BEGIN
DECLARE rowCount INTEGER;
SET #rowCount := ( SELECT COUNT(firstname) FROM testing2 WHERE testing2.firstname = NEW.firstname );
IF (rowCount)
INSERT INTO testing2 (firstname) VALUES (NEW.firstname);
END $$
I'm unable to figure out where did I made the mistake... Any help ??
Try
DELIMITER $$;
CREATE TRIGGER testRef AFTER INSERT ON testing1
FOR EACH ROW
BEGIN
DECLARE rowCount INTEGER;
SET #rowCount := ( SELECT COUNT(firstname) FROM testing2 WHERE testing2.firstname = NEW.firstname );
IF (rowCount) THEN
INSERT INTO testing2 (firstname) VALUES (NEW.firstname);
END IF;
END$$
DELIMITER ;
But maybe you shoud use IF (rowCount)>0
This worked for me :
DELIMITER //
CREATE TRIGGER testRef AFTER INSERT ON testing1
FOR EACH ROW
BEGIN
DECLARE rowCount INTEGER;
SELECT COUNT(firstname) FROM testing2 WHERE testing2.firstname = NEW.firstname INTO rowCount;
IF rowCount = 0 THEN
INSERT INTO testing2 (firstname) VALUES (NEW.firstname);
END IF;
END //
DELIMITER ;

IF Else in stored procedures not working

CREATE PROCEDURE p1
(
IN name_val VARCHAR(255),
OUT iJobID INT
)
BEGIN
IF NOT EXISTS (SELECT id FROM test WHERE id='11')
BEGIN
INSERT INTO test(name) VALUES(name_val);
SET iJobID := LAST_INSERT_ID();
END
ELSE
BEGIN
UPDATE test SET name=name_val WHERE id = 11;
END
INSERT INTO vasu2(vname) VALUES(name_val);
SET #ivD := LAST_INSERT_ID();
INSERT INTO vasu(id, id2) VALUES(iJobID, #ivD);
END;
the IF syntax you are using is most likely for T-SQL. Also, you need to change the delimiter.
DELIMITER $$
CREATE PROCEDURE p1
(
IN name_val VARCHAR(255),
OUT iJobID INT
)
BEGIN
SET #recCount := (SELECT COUNT(*) FROM test WHERE id = 11);
IF #recCount > 0 THEN
INSERT INTO test(name) VALUES(name_val);
SET iJobID := LAST_INSERT_ID();
ELSE
UPDATE test SET name=name_val WHERE id = 11;
END IF;
INSERT INTO vasu2(vname) VALUES(name_val);
SET #ivD := LAST_INSERT_ID();
INSERT INTO vasu(id, id2) VALUES(iJobID, #ivD);
END $$
DELIMITER ;
Using Stored Procedures
You forgot about: delimiter, then, end if
Hope it helps
delimiter $$
CREATE PROCEDURE test.p1
(
IN name_val VARCHAR(255),
OUT iJobID INT
)
BEGIN
IF NOT EXISTS (SELECT id FROM test WHERE id='11') THEN
INSERT INTO test(name) VALUES(name_val);
SET iJobID := LAST_INSERT_ID();
ELSE
UPDATE test SET name=name_val WHERE id = 11;
END IF;
INSERT INTO vasu2(vname) VALUES(name_val);
SET #ivD := LAST_INSERT_ID();
INSERT INTO vasu(id, id2) VALUES(iJobID, #ivD);
END
$$
DELIMITER ;
i think IF not exists does not exist in mysql then