This is my trigger.
I want to make trigger on 1 table (rezervare).
Trigger
DELIMITER //
CREATE TRIGGER verificare_nr_locuri
BEFORE INSERT ON Rezervare
FOR EACH ROW
BEGIN
IF ( SELECT Masa.NrLocuri FROM Rezervare, Masa
WHERE Masa.NumarMasa = Rezervare.NumarMasa ) < Rezervare.NumarPersoane THEN
SET NEW.NumarMasa = NULL;
END IF;
END //
DELIMITER ;
INSERT INTO Rezervare VALUES (123,106,2,'2016-12-11','2016-12-24',5);
INSERT INTO Rezervare VALUES (124,106,2,'2016-12-11','2016-12-24',4);
When I execute the trigger, it has been created. But, when I insert data into table rezervare, It become
#1109 - Unknown table 'rezervare' in field list.
How can I resolve this?
Table
I think you might need to use a JOIN for your SELECT clause.
BEGIN
IF (SELECT Masa.NrLocuri, Rezervare.NumarMasa FROM Masa JOIN Rezervare
WHERE Masa.NumarMasa = Rezervare.NumarMasa) < Rezervare.NumarPersoane THEN
SET NEW.NumarMasa = NULL;
END IF;
Related
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;
I would like to creating a trigger that updates the database when a new message is sent.
If the SenderId and RecipentId already have a conversationId, then update the database so that the New.conversationId = existing conversationId.
Table: mailbox_message
Create a trigger that updates the conversationId to the same value whenever users 11 & 5 send messages to each other.
delimiter $$
create trigger before_insert_conversationId
before insert on data25k29_mailbox_message
for each row
begin
IF ( EXISTS (
SELECT data25k29_mailbox_message.conversationId FROM data25k29_mailbox_message
WHERE (data25k29_mailbox_message.senderId='5'
and data25k29_mailbox_message.recipientId = '11')
and (data25k29_mailbox_message.senderId= '11'
and data25k29_mailbox_message.recipientId= '5')
)
)
THEN
SET NEW.conversationId = data25k29_mailbox_message.conversationId;
ELSE
SET NEW.conversationId = NEW.conversationId;
END IF;
end
$$
The value doesn't change after inserting values. Any help in this regard is greatly appreciated. Thanks
This is my working snippet of this question.
Drop trigger if exists after_insert_conversationId;
delimiter |
CREATE TRIGGER after_insert_conversationId
before insert ON data25k29_mailbox_message
FOR EACH ROW
BEGIN
Declare v1 int;
select conversationId into v1 from data25k29_mailbox_message
where senderId = new.senderId and recipientId = new.recipientId limit 1;
if v1 is NULL
then
set new.conversationId = new.conversationId;
else
set new.conversationId = v1;
End if;
END|
A user is only meant to have up to 3 keys registered to his account at any one time. To add a new key, the user must first delete another key to "make room" for a new one.
I want this to be checked server-side, but I can't get the query to work. Here is what I tried:
IF (SELECT COUNT(serial_key_nbr)
FROM keys_table WHERE user_id = 9) <= 2
THEN INSERT INTO keys_table (user_id, serial_key_nbr)
VALUES (9, 'abc123')
How to do this?
You can use the below mention Script for the same:
INSERT INTO keys_table (user_id, serial_key_nbr)
SELECT 9, 'abc123' FROM DUAL
WHERE
(SELECT COUNT(serial_key_nbr)
FROM keys_table WHERE user_id = 9)<=2
if you want to use an if to do a conditional select then I would put it in a variable like so.
BEGIN
DECLARE var1 INT;
SELECT COUNT(serial_key_nbr) INTO var1
FROM keys_table
WHERE user_id = 9;
IF var1 <= 2
THEN
INSERT INTO keys_table (user_id, serial_key_nbr)
VALUES (9, 'abc123')
END IF;
A trigger might be the way to go. If a condition is met, a trigger before inserting in the table can perform an invalid operation and cause the insert operation to fail:
delimiter $$
create trigger keep_three before insert on keys_table for each row
begin
if (select count(serial_key_nbr) from keys_table where user_id = new.user_id) >= 3 then
insert into non_existent_table (non_existent_field) values (new.user_id);
end if;
end$$
delimiter ;
Ugly, but it might work.
Reference:
"MySQL Triggers: How do you abort an INSERT, UPDATE or DELETE with a trigger?"
Another solution (better I think) is to forcibly delete an entry before attepting the insert. When there are less than 3 entries, the insert procedes normally:
delimiter $$
create trigger keep_three before insert on keys_table for each row
begin
while (select count(serial_key_nbr) from keys_table where user_id = new.user_id) >= 3 do
delete from keys_table where user_id = new.user_id
-- OPTIONAL: Add an ordering criteria to define which entry is deleted first
limit 1;
end while;
end$$
delimiter ;
I think this is cleaner.
A third way (I've found it here). It will return an error message (by signaling sqlstate 45000: Unhandled user defined exception) associated with the defined condition:
delimiter $$
create trigger keep_three before insert on keys table for each row
begin
declare msg varchar(255);
declare n int default 0;
set n = (select count(serial_key_nbr) from keys_table where user_id = new.user_id);
if n >= 3 then
set msg = "INSERT failed: There must be only three entries for each user. Delete an entry first";
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
end if;
end$$
delimiter ;
A cleaner version of my first option.
This is the database vehicle table's trigger
DROP TRIGGER IF EXISTS InsertVehTrig;
DELIMITER $$
CREATE TRIGGER InsertVehTrig AFTER INSERT
ON Vehicle FOR EACH ROW
SWL_return:
BEGIN
DECLARE Cph CHAR(50);
DECLARE DevID CHAR(12);
DECLARE VehID BIGINT;
DECLARE TmpID BIGINT;
DECLARE DevCount INT;
SET Cph = rtrim(ltrim(NEW.cph));
SET VehID = NEW.ID;
SET DevID = NEW.DevID;
if(VehID is null) then
select count(id) into #DevCount from vehicle where (cph=#Cph) or (DevID=#DevID);
-- 条件:当前的车牌号 或 设备ID
end if;
if (DevCount > 1) then -- 如果记录数,超过1,则认为有重复
-- Rollback not supported in trigger
SET #SWV_Null_Var = 0;
Leave SWL_return;
else
if (DevCount = 1) then
select ID INTO #TmpID from Vehicle where (Vehicle.cph = #Cph) or (Vehicle.DevID = #DevID);
if (TmpID != VehID) then -- --如果增加的车牌号码与数据库中的在相同的,则不允许增加
-- Rollback not supported in trigger
Leave SWL_return;
SET #SWV_Null_Var = 0;
end if;
end if;
end if;
update vehicle set cph = #Cph where ID = #VehID;
END;
Right now i m trying to insert new data row in the vehicle table, but error with this
ERROR 1442: Can't update table 'vehicle' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
SQL Statement:
INSERT INTO `gis_server`.`vehicle` (`TrackerNum`, `cph`, `DevID`, `DevType`) VALUES ('1', 'NR09B00555', 'NR09B00555', '2')
those database are designed by 3 party company,
How do i insert data to vehicle table?
You can achieve this by making two changes to your approach:
Firstly, use a BEFORE trigger rather than an AFTER
Secondly, rather than updating the same table, update the NEW table, setting the column value to the new value before the NEW table hits the table targeted by the INSERT.
For example, replace your UPDATE line with the following:
UPDATE NEW SET cph = Cph;
MySQL doesn't allow you to edit the data in the table on which a trigger is created in that trigger, but you can edit the NEW table to modify the values going into that table.
The default initial value of one column in my database is the same as the row's auto-incremented id. I'm trying to use triggers to set it.
CREATE TRIGGER `default_order_value`
AFTER INSERT ON `clusters`
FOR EACH ROW
BEGIN
UPDATE `clusters` SET `order` = NEW.id WHERE `id` = NEW.id;
END
But this keeps throwing a syntax error
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 5
I've tried all sorts of permutations of this with no luck. Can anyone see what I'm doing wrong?
As zerkms said, you need to change the delimeter. But since you only use 1 line of code, you don't need the BEGIN and END. And that way, you don't need to change the delimiter either
CREATE TRIGGER `default_order_value`
AFTER INSERT ON `clusters`
FOR EACH ROW
UPDATE `clusters` SET `order` = NEW.id WHERE `id` = NEW.id;
Since you are getting an error you cannot update the row, I suggest the following:
Do NOT perform the update query at all. On default the order value = the ID value. So when the order value changes, you can update it properly.
If you are requesting the data with php, do something like this:
$order = $row['order'];
if ($order == '')
$order = $row['id'];
After you need it updating, you've got the correct value.
I don't think you can do that. An AFTER INSERT trigger cannot modify the same table, neither by issuing an UPDATE nor by something like this:
CREATE TRIGGER `default_order_value`
AFTER INSERT ON `clusters`
FOR EACH ROW
SET NEW.`order` = NEW.id ;
which results in this error:
> Error Code: 1362. Updating of NEW row is not allowed in after trigger
You can't either use a BEFORE INSERT trigger because then the NEW.id is not known (if you modify the above, the order column will get 0 value after the Insert.
What you can do, is use a transaction:
START TRANSACTION ;
INSERT INTO clusters (id)
VALUES (NULL);
UPDATE clusters
SET `order` = id
WHERE id = LAST_INSERT_ID();
COMMIT ;
You get the error because mysql treats ; in line 5 as the end of your trigger declaration, which obviously leads to the syntax error.
So you need to redefine delimiter before you specify the trigger body:
delimiter |
CREATE TRIGGER `default_order_value`
AFTER INSERT ON `clusters`
FOR EACH ROW
BEGIN
UPDATE `clusters` SET `order` = NEW.id WHERE `id` = NEW.id;
END;
|
delimiter ;
You can create just BEFORE INSERT TRIGGER, it's works like this:
CREATE TRIGGER `default_order_value`
BeFORE INSERT ON `clusters`
FOR EACH ROW
BEGIN
SET NEW.`order` = NEW.id ;
END
same as below we are using
DELIMITER $$
USE `e_store`$$
DROP TRIGGER /*!50032 IF EXISTS */ `Test`$$
CREATE
/*!50017 DEFINER = 'root'#'%' */
TRIGGER `Test` BEFORE INSERT ON `categories`
FOR EACH ROW
BEGIN
DECLARE vtype VARCHAR(250) DEFAULT NULL;
SET vtype = NEW.name;
IF (NEW.MDNAME IS NULL)
THEN
-- SET NEW.MDNAME = 'NA';
SET NEW.MDNAME=MD5(NEW.name);
END IF;
END;
$$
DELIMITER ;
This worked for me:
CREATE TRIGGER `update_table_2`
AFTER UPDATE ON `table_1`
FOR EACH ROW
UPDATE table2
JOIN table_1
SET table_2.the_column = NEW.the_column
WHERE table_2.auto_increment_field = OLD.auto_increment_field