I have two tables, table1 and table2. The SQL is like:
create table table1(
name varchar(100) PRIMARY key not null
);
create table table2(
id bigint PRIMARY key AUTO_INCREMENT,
username varchar(100) not null );
create trigger trigger_test
after insert
on table1
for each ROW
insert into table2 (username)
select new.name from table1;
Every time a row is inserted into table1, this row should also be inserted into table2 by the trigger I created. But after I insert string 'a' into table1, it seems right.
After I insert a second string 'b' into table1, the result appears wrong.
.
For the second time, the same row in table2. Then, I keep inserting rows into table1, the third time is like this:
I am stuck here because I cannot find a solution. Hope to get your help. Thanks in advance.
Your trigger should be either
create trigger trigger_test
after insert
on table1
for each ROW
insert into table2 (username)
values (new.name);
Or
create trigger trigger_test
after insert
on table1
for each ROW
insert into table2 (username)
select new.name from table1 where name = new.name;
Second option is not recomended. But added just to show you where the problem was
Related
I'm trying to create TRIGGERS in MySQL but I got a syntax error message. Here's my code for creating the tables and inserting the values:
The first table:
CREATE TABLE widgetSale (
id INTEGER auto_increment,
item_id INT,
customer_id INT,
quan INT,
price INT,
reconciled INT,
primary key (id));
INSERT INTO widgetSale (item_id, customer_id, quan, price, reconciled) VALUES (1, 3, 5, 1995, 0);
INSERT INTO widgetSale (item_id, customer_id, quan, price, reconciled) VALUES (2, 2, 3, 1495, 1);
INSERT INTO widgetSale (item_id, customer_id, quan, price, reconciled) VALUES (3, 1, 1, 2995, 0);
SELECT * FROM widgetSale;
My first trigger for the first table:
delimiter //
CREATE TRIGGER updateWidgetSale BEFORE UPDATE ON widgetSale for each row
BEGIN
IF NEW.reconciled = 1 THEN
SIGNAL SQLSTATE VALUE '45000'
SET MESSAGE_TEXT = 'cannot update table "widgetSale" after it has been reconciled';
END IF;
END
//
And here are my tables to create trigger for timestamps:
DROP TABLE IF EXISTS widgetSale;
CREATE TABLE widgetCustomer(
id integer auto_increment,
name TEXT,
last_order_id INT,
stamp TEXT,
primary key(id) );
CREATE TABLE widgetSale (
id integer auto_increment,
item_id INT,
customer_id INTEGER,
quan INT,
price INT,
stamp TEXT,
primary key(id) );
CREATE TABLE widgetLog (
id integer auto_increment,
stamp TEXT,
event TEXT,
username TEXT,
tablename TEXT,
table_id INT,
primary key(id));
INSERT INTO widgetCustomer (name) VALUES ('Bob');
INSERT INTO widgetCustomer (name) VALUES ('Sally');
INSERT INTO widgetCustomer (name) VALUES ('Fred');
SELECT * FROM widgetCustomer;
delimiter //
CREATE TRIGGER stampSale before insert on widgetSale for each row
BEGIN
SET NEW.stamp = CURDATE();
update widgetCustomer set last_order_id = new.item_id where widgetCustomer.id = new.customer_id;
update widgetCustomer set stamp = new.stamp;
INSERT INTO widgetLog (stamp, event, username, tablename, table_id) VALUES (NEW.stamp, 'INSERT ', 'TRIGGER', 'widgetSale', NEW.customer_id);
END
//
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (1, 3, 5, 1995);
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (2, 2, 3, 1495);
INSERT INTO widgetSale (item_id, customer_id, quan, price) VALUES (3, 1, 1, 2995);
SELECT * FROM widgetSale;
SELECT * FROM widgetCustomer;
SELECT * FROM widgetLog;
So my problem is:
I could not create the first trigger because it seems the raise function does not exist in MySQL. I was advised to use Signal statement but I don't know what syntax should I put?
I was able to create the trigger for timestamps but I got error code 1442. I don't know what went wrong with my syntax?
*Updated: I was able to solve my problems now, for the second trigger, turns out I need to CREATE TRIGGER BEFORE INSERT, not AFTER INSERT (because otherwise I cannot update the table), and wrote two UPDATE statements to update the widgetCustomer table in which I want to update the id and the stamp column, and I have to do that by writing two separate UPDATE statements.
Summary of errors from above comment thread:
You need to use DELIMITER when defining stored routines in the MySQL client. See https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html
Use the SIGNAL statement to raise errors in a MySQL stored routine. See https://dev.mysql.com/doc/refman/8.0/en/signal.html
Your condition appears to be reconciled = 1, and you reference that column in the row that spawned the trigger as NEW.reconciled. You don't need to SELECT from the table to get that column.
delimiter //
CREATE TRIGGER updateWidgetSale BEFORE UPDATE ON widgetSale
BEGIN
IF NEW.reconciled = 1 THEN
SIGNAL SQLSTATE VALUE '45000'
SET MESSAGE_TEXT = 'cannot update table "widgetSale" after it has been reconciled';
END IF;
END
//
User blabla_bingo noticed you had mistakenly referenced reconciled in some INSERT statements where it didn't belong. I guess it was the result of copy & paste of some lines of code.
Re error 1442: MySQL does not allow you to INSERT/UPDATE/DELETE the same table for which the trigger was spawned. In other words, if the trigger is for an operation ON widgetSale, then you can't UPDATE widgetSale in that trigger.
But you don't need to UPDATE the table to change one column in current row for which the trigger spawned. You simply reference the columns of current row with NEW.columnName like the following to set one column to a scalar value:
SET NEW.stamp = CURDATE();
CURDATE() is an equivalent way of writing DATE(NOW()).
I am trying to use a trigger to insert the updated value to another table. I have two tables (table1 and table2).
I want to copy the new primary key of table1 to a non-primary key field in table2 in hexadecimal value. the primary key is integer type and the other field is varchar.
The code is as follows:
delimiter /
drop trigger if exists a /
create trigger a before insert on table1 for each row
begin
insert into table2 set table1ID= hex(new.id);
end /
insert into table1 set name='Ronnie';
But, the problem is when i insert into table1, the primary key will not be added to table2. it will add 0 instead.
These are the tables:
create table table1 (
id integer not null auto_increment primary key,
name varchar(45) not null
);
create table table2 (
id integer not null auto_increment primary key,
table1ID varchar(45) not null
);
Your trigger is "before insert", and the new generated id is not available yet. Change it to "after insert":
create trigger a after insert on table1 for each row
begin
insert into table2 (warehouseID) values (hex(new.id));
end /
Please see it here.
Insert Into table if a duplicate exits select that row primary key else insert into that table and return last insert id ?
SELECT IF (EXISTS(SELECT * FROM users WHERE userName='adminchat')) THEN
BEGIN
SELECT userId FROM users WHERE userName='adminchat';
end;
ELSE
BEGIN
INSERT INTO `users`( `userRole`, `userName`, `createdOn`, `emailId`, `is_active`, `password`) VALUES (1,'user1_chat',NOW(),'sdmd1#sdmd1.com',1,'123456')
select LAST_INSERT_ID();
END;
If a table contains an AUTO_INCREMENT column and INSERT ... UPDATE inserts a row, the LAST_INSERT_ID() function returns the AUTO_INCREMENT value. If the statement updates a row instead, LAST_INSERT_ID() is not meaningful. However, you can work around this by using LAST_INSERT_ID(expr). Suppose that id is the AUTO_INCREMENT column. To make LAST_INSERT_ID() meaningful for updates, insert rows as follows:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
A way to make things work is to use a dummy column,
so if you have a table with auto_increment column ID and unique key a,b and a smallint dummy column for instance, the query might look like this:
INSERT INTO test (a,b) VALUES ('1','2') ON DUPLICATE KEY UPDATE ID=LAST_INSERT_ID(ID),Dummy = NOT dummy;
Now, SELECT LAST_INSERT_ID(); will return the correct ID.
I have 6 columns in my table:
Id | Name | Mail id | Gender | Contact Number | father name
while inserting a data into table i wanted to check condition like if Name,mailid,contact number already exists then insert should not happen else record should be inserted.
Can any one suggest how to check the condition while inserting a record.
IF NOT EXISTS (SELECT * FROM Table_Name WHERE Condition you are checking)
BEGIN
INSERT INTO ............. ---<----- Your Insert Statement.....
END
You can define an index on multiple columns, e.g.:
CREATE UNIQUE INDEX arbitrary_index_name ON table_name (Name, mailid, contactnumber);
I also faced similar situation, you can do this by adding unique constraint to your table and using 'insert ignore' statement to add data.
Create table statement:
CREATE TABLE Student (
Id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(50),
Mailid VARCHAR(50),
Gender CHAR,
contactnumber BIGINT,
fathername VARCHAR(50),
UNIQUE(NAME,Mailid,contactnumber));
Insert Ignore statement:
INSERT IGNORE INTO student(NAME, Mailid,Gender,contactnumber,fathername) VALUES('Shekhar', 's#s.com', 'M', 987654321, 'Joshi');
This may have a really easy answer. I have done much database stuff for a while. I am trying to get the auto_increment value from one table inserted into the value on another table. is there an easy way of doing this. For eg i have done:
CREATE TABLE table_a (
id int NOT NULL AUTO_INCREMENT,
a_value varchar(4),
PRIMARY KEY (id)
);
CREATE TABLE table_b (
id int NOT NULL,
b_value varchar(15),
FOREIGN KEY (id) REFERENCES table_a (id)
);
Now i want to insert values into the table but I would like 'id' values for table_a and table_b to be the same. So far i have:
INSERT INTO table_a VALUES (NULL, 'foobar');
But I do not know how to go about extracting the auto_incermented 'id' number from table_a into the 'id' value of table_b. I have looked at SELECT #id = LAST_INSERT_ID() but can not get it to work.
You cannot do that at once. You'll have to first insert into the first table:
INSERT INTO table_a (a_value) VALUES ('foobar');
and then insert into the second using the generated id:
INSERT INTO table_b (id, b_value) VALUES (##IDENTITY, 'foobar');
LAST_INSERT_ID() and no need for the select statement part.