Trying to execute 3 insert commands in MySQL temporary Table in Stored Procedure but select command shows only first insert was executed/inserted.
CREATE TEMPORARY TABLE IF NOT EXISTS OtDates (OtDatesList Date, TotalOTMinutes int);
#Fist Insert
insert into OtDates(OtDatesList,TotalOTMinutes) values('2017-04-15', 400);
#Second Insert
insert into OtDates(OtDatesList,TotalOTMinutes) values(#DateOtHalf, #TotalOTMinutesHalf);
#Third Insert
insert into OtDates(OtDatesList,TotalOTMinutes) values(#DateOtFull, #TotalOTMinutesFull);
Select command returns only 2017-04-15, 400 while values from variables in 2nd and 3rd insert are not listed. If I remove the first insert command, the second one gets inserted and not the third one.
EDIT 2 :
Providing complete stored procedure
CREATE DEFINER=`root`#`localhost` PROCEDURE `Test0`()
begin
select #DateOtHalf:=DateofIn, #TotalOTMinutesHalf:=TotalOTMinutes from hrtpunch where TotalOTMinutes >= #ExtraWorkHalfDayInMin and TotalOTMinutes < #ExtraWorkFullDayInMin and EmpID = P_EmpID;
select #DateOtFull:=DateofIn, #TotalOTMinutesFull:=TotalOTMinutes from hrtpunch where TotalOTMinutes >= #ExtraWorkFullDayInMin and EmpID = P_EmpID;
CREATE TEMPORARY TABLE IF NOT EXISTS OtDates (OtDatesList Date, TotalOTMinutes int);
#Fist Insert
insert into OtDates(OtDatesList,TotalOTMinutes) values('2017-04-15', 400);
#Second Insert
insert into OtDates(OtDatesList,TotalOTMinutes) values(#DateOtHalf, #TotalOTMinutesHalf);
#Third Insert
insert into OtDates(OtDatesList,TotalOTMinutes) values(#DateOtFull, #TotalOTMinutesFull);
select * from OtDates;
end
EDIT 3 : Providing Sample Data and Table Structure from "hrtpunch"
Create Statement
CREATE TABLE `hrtpunch` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`TotalOTMinutes` int(11) DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=464 DEFAULT CHARSET=utf8;
Sample Data Insert
insert into hrtpunch (TotalOTMinutes) values(61);
insert into hrtpunch (TotalOTMinutes) values(600);
insert into hrtpunch (TotalOTMinutes) values(301);
insert into hrtpunch (TotalOTMinutes) values(0);
And Int Values returned for ExtraWorkHalfDayInMin is 160 and ExtraWorkFullDayInMin is 240
Try it like this:
CREATE TEMPORARY TABLE IF NOT EXISTS OtDates (OtDatesList Date, TotalOTMinutes int);
INSERT INTO OtDates (OtDatesList,TotalOTMinutes) VALUES
('2017-04-15', 400), (#DateOtHalf, #TotalOTMinutesHalf), (#DateOtHalf, #TotalOTMinutesHalf)
EDIT:
For SQL 2005, the code above doesn't work, so try this:
INSERT INTO OtDates (OtDatesList,TotalOTMinutes)
SELECT '2017-04-15', 400
UNION ALL
SELECT #DateOtHalf, #TotalOTMinutesHalf
UNION ALL
SELECT #DateOtHalf, #TotalOTMinutesHalf
Solved!
DROP TEMPORARY TABLE IF EXISTS `OtDates`;
CREATE TEMPORARY TABLE IF NOT EXISTS OtDates (OtDatesList Date, TotalOTMinutes int);
insert into OtDates(OtDatesList,TotalOTMinutes) select #DateOtHalf:=DateofIn, #TotalOTMinutesHalf:=TotalOTMinutes from hrtpunch where TotalOTMinutes >= #ExtraWorkHalfDayInMin and TotalOTMinutes < #ExtraWorkFullDayInMin and EmpID = P_EmpID;
insert into OtDates(OtDatesList,TotalOTMinutes) select #DateOtFull:=DateofIn, #TotalOTMinutesFull:=TotalOTMinutes from hrtpunch where TotalOTMinutes >= #ExtraWorkFullDayInMin and EmpID = P_EmpID;
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 have the following tables in a database:
CREATE TABLE `CRUISE-RES` (
`cruiseid` INT,
`end-day` DATE,
`start-day` DATE
PRIMARY KEY (`cruiseid`));
CREATE TABLE `ROOM` (
`cruise-id` INT,
`price` FLOAT,
FOREIGN KEY (`cruise-id`));
CREATE TABLE `PROFIT` (
`cruiseid` INT,
`total` FLOAT);
With the following sample table inserts:
-- cruise table inserts
insert into `CRUISE-ID` (`cruiseid`,`start-day`,`end-day`)
values (1, '2022/01/01', '2022/01/05'), (1, '2022/01/05', '2022/01/10'), (2, '2022/01/05', '2022/01/10')
-- room table inserts
insert into ROOM (price,`cruise-id`)
values (5,1), (10,1), (25,2)
I also have the following function that shows the profit of each cruiseid based on the number of days in the CRUISE-RES * price per day.
SELECT c.`cruiseid`, sum(rm.`price`*(DATEDIFF(c.`end-date`, c.`start-date`))) AS 'total_profit'
FROM ROOM rm
JOIN `CRUISE-RES` c
ON rm.`cruise-id` = c.cruiseid
GROUP BY rm.`cruise-id`,'cruiseid'
How can I use this information on a trigger that updates the PROFIT table after each insert into CRUISE-RES table?
create table t(
id int identity(1,1) ,
name varchar(9),
sal int auto_increment
);
insert into t(id,name,sal) values(1,'james',500);
insert into t(id,name,sal)values(2,'raksha',600);
insert into t(id,name,sal) values(3,'mahi',700) ;
insert into t(id,name,sal) values(4,'swathi',800);
insert into t(id,name,sal) values(5,'kruthi',900);
insert into t(id,name,sal) values(6,'radha',1000);
insert into t(id,name,sal) values(7,'amal',400);
create function fun()
returns int
As
begin(
return(sal'+'2)
end )
select name,fun(sal) from t where id=7;
I want to use a function inside a select query.
This is my test database.
When I use a select, get a result, but the function is running twice... why? I want to insert one row in this case.
Help, please!
create database db1_test;
use db1_test;
create table t1(
id int(11) primary key auto_increment,
t1col1 varchar(20) not null,
t1col2 int(1) not null
);
create table t2(
id int(11) primary key auto_increment,
t2col1 int(11) not null,
t2col2 datetime
);
insert into t1 (t1col1, t1col2) values ('row1', 1);
insert into t1 (t1col1, t1col2) values ('row2', 0);
insert into t1 (t1col1, t1col2) values ('row4', 1);
drop function if exists func1;
DELIMITER $$
CREATE FUNCTION func1(id int) RETURNS datetime
BEGIN
insert into t2 (`t2col1`, `t2col2`) values (id, now());
RETURN now();
END $$
DELIMITER ;
TEST :
SELECT id, t1col2, func1(id) FROM `t1` WHERE 1 and `t1`.`t1col1`='row1';
SELECT id, t1col2, func1(id) FROM `t1` WHERE 1 and `t1`.`t1col1`='row2';
SELECT id, t1col2, func1(id) FROM `t1` WHERE 1 and `t1`.`t1col1`='row4';
Functions are generally used to store reuseable code which returns a scalar value from a calculation or transformation. I think you could
insert into t2(t2col1,t2col2)
SELECT id, now()
FROM `t1`
WHERE `t1`.`t1col1`='row1';
I'm trying to use "MERGE" in two temporary tables, I failed to get results.
Error: Incorrect syntax near the keyword 'AS'.
Create Table #tmp1
(
[Server] varchar(4),
[DateTime] datetime,
IdComponent int,
AvgTimeTaken int
)
Create Table #tmp2
(
[Server] varchar(4),
[DateTime] datetime,
IdComponent int,
AvgTimeTaken int
)
insert into #tmp1 values ('BE01','2012-08-01 00:00:00',1,100)
insert into #tmp1 values ('BE02','2012-08-01 00:00:00',2,100)
insert into #tmp1 values ('BE03','2012-08-01 00:00:00',3,100)
insert into #tmp1 values ('BE04','2012-08-01 00:00:00',4,100)
insert into #tmp1 values ('BE05','2012-08-01 00:00:00',5,100)
insert into #tmp2 values ('BE01','2012-08-01 00:00:00',1,100)
insert into #tmp2 values ('BE02','2012-08-01 00:00:00',2,200)
insert into #tmp2 values ('BE03','2012-08-01 00:00:00',3,300)
insert into #tmp2 values ('BE04','2012-08-01 01:00:00',4,400)
insert into #tmp2 values ('BE05','2012-08-01 02:00:00',5,500)
MERGE #tmp1 AS [Target]
USING #tmp2 AS [Source]
ON ([Target].[Server] = [Source].[Server]
AND [Target].[DateTime] = [Source].[DateTime]
AND [Target].[IdComponent] = [Source].[IdComponent])
WHEN MATCHED THEN
UPDATE
SET [Target].AvgTimeTaken = [Source].AvgTimeTaken
WHEN NOT MATCHED THEN
INSERT ([Target].[Server], [Target].[DateTime], [Target].IdComponent, [Target].AvgTimeTaken)
VALUES ([Source].[Server], [Source].[DateTime], [Source].IdComponent, [Source].AvgTimeTaken);
I'm not sure I can be wrong. At the end also has a semicolon.
Help please!
I've run into this error before and it was because SQL Server 2008 R2 does not support the merge syntax unless you set the compatibility mode by executing the following:
ALTER DATABASE mydatabase SET COMPATIBILITY_LEVEL = 100
Where mydatabase is the name of the database you want to apply this to.
Take out the Target aliases in the INSERT clause.
Create Table #tmp1 (
[Server] varchar(4),
[DateTime] datetime,
IdComponent int,
AvgTimeTaken int
);
Create Table #tmp2 (
[Server] varchar(4),
[DateTime] datetime,
IdComponent int,
AvgTimeTaken int
);
insert into #tmp1 values ('BE01','2012-08-01 00:00:00',1,100);
insert into #tmp1 values ('BE02','2012-08-01 00:00:00',2,100);
insert into #tmp1 values ('BE03','2012-08-01 00:00:00',3,100);
insert into #tmp1 values ('BE04','2012-08-01 00:00:00',4,100);
insert into #tmp1 values ('BE05','2012-08-01 00:00:00',5,100);
insert into #tmp2 values ('BE01','2012-08-01 00:00:00',1,100);
insert into #tmp2 values ('BE02','2012-08-01 00:00:00',2,200);
insert into #tmp2 values ('BE03','2012-08-01 00:00:00',3,300);
insert into #tmp2 values ('BE04','2012-08-01 01:00:00',4,400);
insert into #tmp2 values ('BE05','2012-08-01 02:00:00',5,500);
MERGE #tmp1 AS Target
USING #tmp2 AS Source
ON (Target.Server = Source.Server
AND Target.DateTime = Source.DateTime
AND Target.IdComponent = Source.IdComponent)
WHEN MATCHED THEN
UPDATE
SET Target.AvgTimeTaken = Source.AvgTimeTaken
WHEN NOT MATCHED THEN
INSERT (Server, DateTime, IdComponent, AvgTimeTaken)
VALUES (Source.Server, Source.DateTime, Source.IdComponent, Source.AvgTimeTaken);
The insert column list used in the MERGE statement cannot contain multi-part identifiers. Use single part identifiers instead.