MYSql Trigger statement - mysql

I can't seem to get one of the triggers im trying to make to work at the moment it looks like this (has been messed around with alot in an attempt to get it to work so probably doesn't make any sense now)
CREATE TRIGGER `insertproductebay` AFTER INSERT ON `product`
FOR EACH ROW INSERT INTO eBayLinked
(product_id,company_id,eBay_ID,ebay_token_id,ebay_username)
SELECT ebay_token_id,ebay_username
FROM
'company'
WHERE
'company_id' = 'company_id'
VALUES
(NEW.product_id,NEW.company_id,NEW.eBay_ID,ebay_token_id,ebay_username)

The following makes it past the 1065 error
Care must be taken to use back-ticks around table and column names, and not to use single quotes there.
drop trigger if exists `insertproductebay`;
DELIMITER $$
CREATE TRIGGER `insertproductebay` AFTER INSERT ON `product`
FOR EACH ROW
INSERT INTO eBayLinked
(product_id,company_id,eBay_ID,ebay_token_id,ebay_username)
SELECT NEW.product_id,NEW.company_id,NEW.eBay_ID,ebay_token_id,ebay_username
FROM `company`
WHERE `company_id` = 'company_id'
$$
DELIMITER ;
The remaining problem as I see it could be what are you meaning by
WHERE `company_id` = 'company_id'
in a trigger. Because a trigger is a faceless piece of code that runs in the background, succeeding or failing silently. In other words, there is no user interface associated with it.

You can't mix the INSERT ... SELECT and INSERT ... VALUES syntaxes in that way. However, you can provide literal values in a select list, thusly:
CREATE TRIGGER insertproductebay AFTER INSERT ON product FOR EACH ROW
INSERT INTO eBayLinked
(product_id, company_id, eBay_ID, ebay_token_id, ebay_username)
SELECT NEW.product_id, NEW.company_id, NEW.eBay_ID, ebay_token_id, ebay_username
FROM company
WHERE company_id = NEW.company_id

Related

stored procedures trying to insert into two tables: error 1136

Im trying to get this program to add a new row into two different tables: bilde and student.
The values entered into bilde should come from the values used in student.
At this point i get this message: error code: 1136. Column count dosen't match value at row 1, and im not quite sure what to do to fix this.
DELIMITER $$
DROP PROCEDURE IF EXISTS NyStudent $$
CREATE PROCEDURE NyStudent (
brukernavn VARCHAR(45)
,fornavn VARCHAR(45)
,etternavn VARCHAR(45)
,klassekode INT
)
BEGIN
START TRANSACTION;
INSERT INTO bilde (filnavn, beskrivelse)
VALUES (CONCAT('bilder/', fornavn, '.jpg'), CONCAT('bilde av ', fornavn, ' ', etternavn));
INSERT INTO student
VALUES ('donaldduck','donald','duck','1');
COMMIT;
END$$
DELIMITER ;
CALL NyStudent('donaldduck','donald','duck','1');
Try adding the column names in the 'INSERT INTO' statement for students, as that should be the major reason for column count error.
Also, Even when we insert values for every column of the table, it is a best practice to include column names after INSERT INTO statement. Following this would avoid any breakage in code to a certain extent, even on schema changes in the future.

AFTER INSERT Trigger to insert data into a different table after inserting it into initial table

Hello and thanks in advance for any help given!
I have created a very simple database for an electronics online shop.
Among the other tables I have a tbl_orders for orders being placed manually (user inserts the product_id, number of units, payment_details_id and so on manually) and I want to make an AFTER INSERT trigger on tbl_orders that would send the order_id (which is tbl_order's PK) to a table called purchase_history.
The table purchase_history also has a purchase_date column. It's PK is purchase_id, with order_id as a FK.
I am unfamiliar with triggers but I've tried all sorts of simple queries inside a trigger with no luck, though the errors I was getting were getting "better" if one could call it that.
The last try I had was this:
CREATE DEFINER = CURRENT_USER TRIGGER `onlineshop`.`tbl_orders_AFTER_INSERT` AFTER INSERT ON `tbl_orders` FOR EACH ROW
BEGIN
INSERT INTO purchase_history (order_id)
VALUES (NEW.order_id);
INSERT INTO purchase_history ( purchase_date )
VALUES (purchase_date = NOW());
END
I am using MYSQL Workbench, which is great but also, sometimes, slightly buggy or confusing.
CREATE TRIGGER `tbl_orders_AFTER_INSERT` AFTER INSERT ON `tbl_orders`
FOR EACH ROW BEGIN
INSERT INTO purchase_history (order_id, purchase_date) VALUES (NEW.order_id, NOW());
END;
This way your insert would make more sense, as you would want both of the data in the same row in the history, I'd guess.
If the DEFINER-line is needed:
CREATE DEFINER = CURRENT_USER
TRIGGER stuff.`tbl_orders_AFTER_INSERT` AFTER INSERT ON `tbl_orders`
FOR EACH ROW
INSERT INTO purchase_history (order_id, purchase_date) VALUES (NEW.order_id, NOW());
I tried some things, mysql seems not to like begin, end and DEFINER = ... at the same time when creating triggers. Though BEGIN and END are not needed with triggers so there is no problem in removing them from your statement.
You can use the below syntax to execute it. First we need to change delimiter if there is multiple statament.
DELIMITER #
create trigger SportsTriggerInsert after insert on sports
for each row begin
insert into settings(sports_id, auto_add_on_matches)
values (new.id, 0);
end;#
DELIMITER ;

How to create a table that lists all the names in one table and counts the number of times it appears in another one?

I have to create a table named vecesCarcel which whenever I insert a name, it automatically adds another cell with the number of times the name appears in another table. So far I've tried with triggers this, but without result:
USE lordfarquaad;
CREATE TABLE IF NOT EXISTS vecesCarcel(
nombrePersonaje VARCHAR(10),
veces INTEGER(5) UNSIGNED)
ENGINE=InnoDB;
ALTER TABLE vecesCarcel
ADD CONSTRAINT vecesCarcelFK1 FOREIGN KEY(nombrePersonaje)
REFERENCES personajes(nombrePersonaje)
ON DELETE CASCADE ON UPDATE CASCADE;
USE lordfarquaad;
DELIMITER $$
CREATE PROCEDURE checkvecescarcel(IN nombre VARCHAR(10),OUT veces INT(5))
BEGIN
SET veces=(SELECT COUNT(*) FROM historiales WHERE nombrePersonaje=nombre);
END
$$
CREATE TRIGGER vecesCarcel_Insert BEFORE INSERT ON vecesCarcel FOR EACH ROW
BEGIN
CALL checkvecescarcel(NEW.nombrePersonaje,NEW.veces);
END;
$$
If you want to use a trigger, you have to set the new.veces-value inside the trigger:
CREATE TRIGGER vecesCarcel_Insert BEFORE INSERT ON vecesCarcel FOR EACH ROW
SET new.veces=(SELECT COUNT(*) FROM historiales
WHERE nombrePersonaje=NEW.nombrePersonaje);
You might want to create an on update-trigger, too (same code, so you can aswell put select count(*)... in a function and use set new.veces = myfnct(new.nombrepersonaje)).
But keep in mind your count will not update itself if you change anything in the table historiales (e.g. add another entry with the name in the list). So, depending on your setup, and if your historiales-table can change, or if you just might want to try a different approach, you can try a view:
create view vecesCarcelView as
select nombrePersonaje,
(select count(*)
from historiales
where vecesCarcel.nombrePersonaje=historiales.nombrePersonaje) as veces
from vecesCarcel;
(If you don't care so much about the order, you can do this with a left join and a group by too; and you could actually use the view with the whole personajes-table to display the count for all known names.)

create trigger on update to insert old values into other table in MYSQL

I have two tables. The first is my person table which has id, name, creation_date as values, I have a old_person table (id, name, modified_date) which I want to populate the value of person before it actually changes. How would I go about that? I have tried triggers but failed.
I tried as follows
create trigger Person_Trigger Update on person
before update
as
insert into old_person(id, name, modified)
select id, new.name, getdate()
from person
It's giving me syntax errors...Not many Trigger references out there either, a little push would be greatly appreciated!
Have a look at the following example
SQL Fiddle DEMO
IO hade a bit of trouble myself, but from How to Create Triggers in MySQL there was a line that made me think
The first MySQL command we’ll issue is a little unusual:
DELIMITER $$
Our trigger body requires a number of SQL commands separated by a
semi-colon (;). To create the full trigger code we must change
delimiter to something else — such as $$.
Finally, we set the delimiter back to a semi-colon:
DELIMITER ;
So in the SQL Fiddle I changed the query terminator to GO and that seemed top work.
CREATE TABLE person
(
id INT,
name varchar(20)
)
GO
CREATE TABLE old_person
(
id INT,
name varchar(20),
modified DATETIME
)
GO
CREATE TRIGGER Person_Trigger before update on person
FOR EACH ROW BEGIN
INSERT INTO old_person(id, name, modified)
VALUES (OLD.id, OLD.name, NOW());
END
GO
INSERT INTO person VALUES (1,'TADA')
GO
UPDATE person SET name = 'FOO'
GO
Try this:
DELIMITER \\
CREATE TRIGGER `Person_Trigger`
BEFORE UPDATE ON `Person`
FOR EACH ROW
BEGIN
DECLARE date_modified datetime;
SET date_modified = NOW();
INSERT INTO old_person(id, name, modified)
VALUES (OLD.id, OLD.name, date_modified);
END\\
This syntax works for me on my own projects. You may also need to declare delimiters before you begin the trigger. Also if you want to use the NEW keyword it should be AFTER update. Switch to the OLD keyword if you are going to keep using BEFORE update on your trigger.

MySQL Trigger INSERT copy's rows

I am trying to create a trigger (this is my first trigger, and question, so be gentle) that will insert new rows into two different tables.
* Edit *
Adding this in as I forgot to mention it until ypercube answered.
I am trying to avoid listing all of the column names, as in the real world usage the table this will be used on has a very large number of columns (not my design, too late to refactor).
* End Edit *
Here's what I have so far.
CREATE TABLE test_table (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
message VARCHAR(255)
);
CREATE TABLE test_table_copy LIKE test_table;
DELIMITER $$
CREATE TRIGGER copy_test_table_data AFTER INSERT ON test_table
FOR EACH ROW
BEGIN
INSERT INTO test_table_copy SELECT * FROM NEW;
END;$$
DELIMITER ;
Unfortunately this results in an error.
mysql> INSERT INTO test_table VALUES (1, 'This is a message');
ERROR 1146 (4502): Table 'test_db.NEW' doesn't exist
I am not quite sure what the problem is, I thought NEW referred the table data was being inserted into?
You could possibly get a list of column names in that table from information_schema views, then use them to create a prepared statement (using cursor to iterate column names) and CONCAT() function to glue together the query string. Then execute the prepared statement.
Seems very contrived even to me, and I'm not sure it would work (and if it did, how efficient it would be)