Following up to see if there is a way, know this might be simple for you guys:
I need to create a table with 5 columns where columns(CostPrice) and columns(SellPrice) need to add a value into columns(Difference) in MySQL. In the example let's say I have items I wish to load and upon selling them I want that Difference calculated in the database not through a view because I'd like to reference that "Difference" value in another table when I'll at a later stage be doing a view.
What I'm trying to achieve:
itemAdd/itemName/costPrice/sellPrice/difference
2019-08-22/Table/100/150/50
CREATE TABLE Results (
itemAdd Timestamp,
itemName varchar(255) NOT NULL,
costPrice int(11) NOT NULL,
sellPrice int(11) NOT NULL,
(costPrice - sellPrice) as 'difference'
)
Reason why I want to do this through table create is because I'd update the costPrice and sellPrice of the items and would like to keep track of how the difference changed, but at the same time I'd like to reference the difference column from another table so that value shouldn't stay statically the same. Hope this makes sense. . .
If you set up insert/update triggers, you can determine the difference any time there is a change.
(live sandbox example: https://www.db-fiddle.com/f/8DVeXFdsrEBwHg168GZU2o/22)
Update your table to define the difference column.
CREATE TABLE Results (
itemAdd Timestamp,
itemName varchar(255) NOT NULL,
costPrice int(11) NOT NULL,
sellPrice int(11) NOT NULL,
difference int(11) NOT NULL
);
Then define triggers to handle the insert/updates:
-- handle inserts
DELIMITER $$
CREATE TRIGGER trg_insert_price_diff
BEFORE INSERT ON Results
FOR EACH ROW
BEGIN
SET NEW.difference = NEW.sellPrice - NEW.costPrice;
END$$
DELIMITER ;
-- handle updates
DELIMITER $$
CREATE TRIGGER trg_update_price_diff
BEFORE UPDATE ON Results
FOR EACH ROW
BEGIN
SET NEW.difference = NEW.sellPrice - NEW.costPrice;
END$$
DELIMITER ;
Related
I put 10,000 avatar photos on a server and I would like for each row inserted into the 'studenttable' table, the 'photo' column to be the concatenation of the url of the folder of my photos + the id of the inserted student.
However, the CONCAT function returns a NULL value with the basic trigger used.
First, here is the above mentioned table :
CREATE TABLE `studenttable` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`gender` enum('Male','Female','Other') NOT NULL,
`email` varchar(100) DEFAULT NULL,
`birthDate` date DEFAULT NULL,
`photo` varchar(535) DEFAULT NULL,
`mark` double DEFAULT NULL,
`comment` varchar(535) DEFAULT NULL,
PRIMARY KEY (`id`)
)
and here is the basic trigger I created:
DELIMITER $$
create trigger IMAGE_LienApi
before insert on studenttable
for each row
begin
set NEW.photo = CONCAT('https://url-of-folder-with-my-images/',NEW.id,'.png');
end$$
DELIMITER ;
For information, the images are referenced in this way:
number.png
So when I insert a new student with this trigger, the photo column is always set to NULL.
The problem must come from NEW.id, because when I replace this value with a string, it works.
I also tried with
NEW.photo = 'https://url-of-folder-with-my-images/' + CONVERT(VARCHAR(5),NEW.id),'.png';
but it did not work
Thank you in advance for your help and if someone could explain to me especially why the CONCAT does not work, that would be great !
CONCAT() returns NULL if any of its arguments are NULL.
In a BEFORE INSERT trigger, the NEW.id value is NULL. It hasn't been generated yet.
But in an AFTER INSERT trigger, it's too late to change the NEW.photo column of your row. You can't change columns in an AFTER trigger.
You cannot make a BEFORE INSERT trigger to concatenate an auto-increment value with other columns. The best you can do is let the INSERT complete, and then subsequently do an UPDATE to change your photo column.
The alternative is to forget about using the builtin AUTO_INCREMENT to generate id values, instead generate them some other way and specify the value in your INSERT statement.
so I have this two tables which both have some trigger, both are AFTER INSERT; I dont exactly know how to call it but I hope the title is not so inaccurate. :)
I'm currently new to triggers in general so bear with me on this one please.
What happens is that for every new episode entry I need to updated the count of episodes per season. And when a new entry in the season table a new episode shall be created (a trailer).
I'm currently using MySQL 5.7.17; This triggers work in DB2 but in MySQL I just couldnt get them to work.
I just keep getting the error that says that I can't update the table from which the statement was called:
Can't update table 'seasons' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
If you can help me, or not, anyways any ideas THANKS IN ADVANCE!
CREATE TABLE episodes (
episodeId INTEGER NOT NULL AUTO_INCREMENT,
seasonId INTEGER NOT NULL,
number INTEGER NOT NULL,
date DATE NOT NULL,
title VARCHAR(256) NOT NULL,
summary TEXT,
PRIMARY KEY(episodeId)
);
CREATE TABLE seasons (
seasonId INTEGER NOT NULL AUTO_INCREMENT,
startDate DATE NOT NULL,
name VARCHAR(128) DEFAULT 'Unknown season',
numberOfEpisodes SMALLINT NOT NULL DEFAULT 0,
PRIMARY KEY(seasonId)
);
/* TRIGGERS */
/* trigger to increment the numberOfEpisodes in seasons */
CREATE TRIGGER newEpisode
AFTER INSERT ON episodes
FOR EACH ROW
BEGIN -- I also tried without the Begin-End statement
UPDATE seasons SET numberOfEpisodes = numberOfEpisodes + 1
WHERE seasons.seasonId = NEW.seasonId;
END;
;
/* Each season has a trailer as episode 0 */
CREATE TRIGGER newSeason
AFTER INSERT ON seasons
FOR EACH ROW
BEGIN -- I also tried without the Begin-End statement
INSERT INTO episodes (seasonId, number, date, title, summary)
VALUES (NEW.seasonId, 0, CURRENT_TIMESTAMP, 'Trailer', 'Episode 0 = Trialer');
END;
;
I've created a table in mySQL like this:
CREATE TABLE IF NOT EXISTS `LibraryManager`.`Card` (
`card_id` INT NOT NULL AUTO_INCREMENT,
`card_registerDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`card_expiredDate` TIMESTAMP,
PRIMARY KEY (`card_id`))
ENGINE = InnoDB;
Now I want to set the default value of card_expiredDate to card_registerDate + 30 or CURRENT_TIMESTAMP + 30 (30 day from register date). Is there any way to do that?
Thank you very much for reading this.
Setting the default value for expiry column using create statement is not possible as such, instead use trigger. For that you will have to slightly modify you create statement. Just change the datatype of expiry column, your new query:
CREATE TABLE IF NOT EXISTS `LibraryManager`.`Card` (
`card_id` INT NOT NULL AUTO_INCREMENT,
`card_registerDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`card_expiredDate` DATETIME,
PRIMARY KEY (`card_id`))
ENGINE = InnoDB;
and then fire the following trigger
CREATE TRIGGER before_insert_library_card
BEFORE INSERT ON `LibraryManager`.`Card`
FOR EACH ROW
SET new.card_expiredDate = adddate(CURRENT_TIMESTAMP,30);
hope this helps.
P.S: Triggers slow down your insert operations(or whatever operation they are applied before/after). I suggest you set these values programmatically using php/python or whatever the backend you are using.
Related:
Can I use a function for a default value in MySql?
Create an AFTER INSERT trigger, it will do the job for you:
DELIMITER $$
CREATE TRIGGER set_expiration_date
AFTER INSERT ON `LibraryManager` FOR EACH ROW
BEGIN
UPDATE LibraryManager
SET card_expiredDate = DATE_ADD(NEW.card_registerDate, INTERVAL 30 DAY)
WHERE card_id = NEW.card_id;
END;
$$
DELIMITER ;
PS: I haven't tested it, if you get any error do let me know.
I am trying to create a fairly complicated Trigger and I'm not sure if it can be done on phpMyAdmin.
Right now I have this query that creates a table with all the information I need from it.
CREATE TABLE SeniorDB_Shipping
SELECT
SeniorDB_Invoice.ID_Order,
SeniorDB_Customer.MCT_Code,
SeniorDB_Customer.Customer_Name,
SeniorDB_Customer.Customer_Address,
SeniorDB_Customer.Customer_City,
SeniorDB_Customer.Customer_State,
SeniorDB_Invoice.Shipping_Company
FROM SeniorDB_Customer
Join SeniorDB_Invoice ON SeniorDB_Customer.MCT_Code = SeniorDB_Invoice.MCT_Code
As you can see in the image, when I run the query, it pulls in information from the tables above the information. I'm trying (and failing) to create a trigger that will do this same thing without having to create a brand new table every single time. All the other posts I have seen are similar in regards to creating a table instead of inserting to a table.
What the trigger does is, when I enter the ID_Order, the rest of the information will get pulled from the database.
This is the trigger I have so far:
delimiter ~
create trigger SeniorDB_Shipping before insert on SeniorDB_Shipping
for each row begin
set new.SeniorDB_Shipping.MCT_Code = new.SeniorDB_Customer.MCT_Code,;
set new.SeniorDB_Shipping.Customer_Name = new.SeniorDB_Customer.Customer_Name,;
set new.SeniorDB_Shipping.Customer_Address = new.SeniorDB_Customer.Customer_Address,;
set new.SeniorDB_Shipping.Customer_City = new.SeniorDB_Customer.Customer_City,;
set new.SeniorDB_Shipping.Customer_State = new.SeniorDB_Customer.Customer_State,;
set new.SeniorDB_Shipping.Shipping_Company = new.SeniorDB_Customer.Shipping_Company,;
end~
delimiter ;
I feel like I'm right there. I just can't link it to when I enter the ID_Order.
This is the page if you would like to see the databases: http://polonium.forest.usf.edu/~sngamwon/SeniorProject/SeniorDB_Order.php
Ok, so you'll need to run this once:
/* Create the table with a primary key */
create table `SeniorDB_Shipping` (
`id` INT unsigned AUTO_INCREMENT NOT NULL,
primary key(id),
`ID_Order` int NOT NULL,
`MCT_Code` int NOT NULL,
`Customer_Name` varchar(255) NOT NULL,
`Customer_Address` varchar(255) NOT NULL,
`Customer_City` varchar(255) NOT NULL,
`Customer_State` varchar(255) NOT NULL,
`Shipping_Company` varchar(255) NOT NULL
) ENGINE=MyISAM CHARACTER SET=utf8 COLLATE utf8_general_ci;
Then you can run
/* Insert statement */
INSERT INTO `SeniorDB_Shipping` (
`ID_Order`,
`MCT_Code`,
`Customer_Name`,
`Customer_Address`,
`Customer_City`,
`Customer_State`,
`Shipping_Company`
) SELECT
invoice.ID_Order,
customer.MCT_Code,
customer.Customer_Name,
customer.Customer_Address,
customer.Customer_City,
customer.Customer_State,
invoice.Shipping_Company
FROM
SeniorDB_Customer as customer
Join SeniorDB_Invoice as invoice
ON customer.MCT_Code = invoice.MCT_Code;
I've run this in my own PHPMyAdmin, so it works. But I obviously don't have your schema. Known issues:
This will populate SeniorDB_Shipping with ALL the data from your two tables each time. Modify the query as required to select only recent data if that's not what you want. If ID_Order is a primary key you could check that doesn't already exist.
I want to create a column with default value as null and when any operation is performed it should change to 0. How do i do this in mysql database?
Here example how to add colum in existing table with default value
ALTER TABLE `test1` ADD `no` INT NULL DEFAULT NULL ;
When you call function then you have to write following query
UPDATE test1 SET `no` = '0' WHERE `test1`.`id` =your_id;
CREATE TABLE test
(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
test_id INT,
cost FLOAT(5,2) DEFAULT NULL,
);
each time when you do some operation on that you need to update it as #Sadikhasan
or write a trigger that will update it to zero automatically.
if the operation you want to perform is read then write trigger on ON SELECT
if the operation you want to perform is update then write trigger on ON UPDATE
like wise for others.