I'm rather new to MySQL and am encountering an error with my procedure, I want to be able to call the same thing for updates, inserts and deletes to a to my table so need a procedure to call.
I've looked at MySQL Fire Trigger for both Insert and Update and The MySQL "DELIMITER" keyword isn't working as well as some other but nothing helped. (the delimiter keyword also doesnt work producing a sepperate error but that doesnt help)
The error is this and I cant work out what it means:
"Error
SQL query:
-- trigger on work log change
DROP PROCEDURE IF EXISTS PROC_TRACK_CHANGES CREATE DEFINER = root#localhost PROCEDURE PROC_TRACK_CHANGES BEGIN INSERT INTO CHANGES( LoggedTimeStamp, EmployeeID, LogTimeStamp, ProposalID, WorkDone )
SELECT NOW( ) , EmployeeID, LogTimeStamp, ProposalID, WorkDone
FROM WORKLOG;
MySQL said:
#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 'CREATE DEFINER=root#localhost PROCEDURE PROC_TRACK_CHANGES
BEGIN
INSERT INTO ' at line 3"
The errorred code in question is this:
CREATE TABLE WORKLOG(
EmployeeID BIGINT UNSIGNED NOT NULL UNIQUE, -- FKEY PKEY
LogTimeStamp TIMESTAMP, -- PKEY
ProposalID BIGINT UNSIGNED NOT NULL UNIQUE, -- FKEY
WorkDone VARCHAR(200),
CONSTRAINT WORKLOG_FOREIGN_KEY_EMP FOREIGN KEY (EmployeeID) REFERENCES EMPLOYEES (EmployeeID),
CONSTRAINT WORKLOG_FOREIGN_KEY_PRO FOREIGN KEY (ProposalID) REFERENCES PROPOSALS (ProposalID),
CONSTRAINT WORKLOG_PROPOSALS_PRIMARY_KEY PRIMARY KEY (EmployeeID, LogTimeStamp)
);
CREATE TABLE CHANGES(
LoggedTimeStamp TIMESTAMP, -- PKEY
EmployeeID BIGINT UNSIGNED NOT NULL UNIQUE, -- FKEY
LogTimeStamp TIMESTAMP, -- fkey
ProposalID BIGINT UNSIGNED NOT NULL UNIQUE, -- FKEY
WorkDone VARCHAR(200),
CONSTRAINT CHANGES_FOREIGN_KEY_EMP FOREIGN KEY (EmployeeID) REFERENCES EMPLOYEES (EmployeeID),
CONSTRAINT CHANGES_FOREIGN_KEY_PRO FOREIGN KEY (ProposalID) REFERENCES PROPOSALS (ProposalID),
CONSTRAINT CHANGES_PRIMARY_KEY PRIMARY KEY (LoggedTimeStamp)
);
-- trigger on work log change
DROP PROCEDURE IF EXISTS PROC_TRACK_CHANGES
CREATE DEFINER=root#localhost PROCEDURE PROC_TRACK_CHANGES
BEGIN
INSERT INTO CHANGES (LoggedTimeStamp, EmployeeID, LogTimeStamp, ProposalID, WorkDone)
SELECT now(), EmployeeID, LogTimeStamp, ProposalID, WorkDone FROM WORKLOG;
END;
DROP TRIGGER IF EXISTS TR_WORKLOG_UPDATE
CREATE DEFINER=root#localhost TRIGGER TR_WORKLOG_UPDATE
BEFORE UPDATE ON 'WORKLOG'
FOR EACH ROW
BEGIN
CALL PROC_TRACK_CHANGES();
END;
DROP TRIGGER IF EXISTS TR_WORKLOG_INSERT
CREATE DEFINER=root#localhost TRIGGER TR_WORKLOG_INSERT BEFORE INSERT ON WORKLOG
FOR EACH ROW
BEGIN
CALL PROC_TRACK_CHANGES();
END;
DROP TRIGGER IF EXISTS TR_WORKLOG_DELETE
CREATE DEFINER=root#localhost TRIGGER TR_WORKLOG_DELETE BEFORE DELETE ON WORKLOG
FOR EACH ROW
BEGIN
CALL PROC_TRACK_CHANGES();
END;
It's probably something simple that i'm missing but the MYSQL debugger confuses me.
many thanks!
A procedure drop is a single statement and a procedure create too. Seperate them with the delimiter.
Another thing is that you need to define another delimiter than ;. Otherwise the DB will termiante every statement at the ; which makes some trigger and procedure definitions incomplete. So use for example
delimiter |
DROP PROCEDURE IF EXISTS PROC_TRACK_CHANGES
|
CREATE DEFINER=root#localhost PROCEDURE PROC_TRACK_CHANGES
BEGIN
INSERT INTO CHANGES (LoggedTimeStamp, EmployeeID, LogTimeStamp, ProposalID, WorkDone)
SELECT now(), EmployeeID, LogTimeStamp, ProposalID, WorkDone FROM WORKLOG;
END
|
Try this:
DROP PROCEDURE IF EXISTS PROC_TRACK_CHANGES;
Notice the semi-colon at the end.
You should specify a temporary delimiter other than semi-colon, and use that delimiter at the end of both your DROP PROCEDURE and CREATE PROCEDURE statements.
Also you need to add parentheses after the procedure name in the CREATE PROCEDURE statement even if it takes no arguments.
This should work for you:
DELIMITER $$
DROP PROCEDURE IF EXISTS PROC_TRACK_CHANGES $$
CREATE DEFINER=root#localhost PROCEDURE PROC_TRACK_CHANGES ()
BEGIN
INSERT INTO CHANGES (LoggedTimeStamp, EmployeeID, LogTimeStamp, ProposalID, WorkDone)
SELECT now(), EmployeeID, LogTimeStamp, ProposalID, WorkDone FROM WORKLOG;
END $$
DELIMITER ;
Related
//This is the code
create procedure st_insertRole(
#name varchar(30) //I get the error here
as
insert into roles values(#name)
);
here is the screenshot
My SQL does not allow session variables to be used for procedure parameters. You also have parentheses misplaced. The code in MySQL would look more like:
delimiter $$
create procedure st_insertRole (
in_name varchar(30)
)
begin
insert into roles (name)
values (in_name);
end; $$
The syntax is wrong
create procedure st_insertRole(
name_ varchar(30) )
insert into roles values(name_)
;
To quite simply put how my SP looks it is basically like this atleast syntax wise
DELIMITER $$
DROP PROCEDURE IF EXISTS `info_insert_or_update` $$
CREATE PROCEDURE `info_insert_or_update` (
IN in_id bigint,
IN in_name varchar(150),
IN in_details varchar(150))
START TRANSACTION;
INSERT INTO infos (id, name)
VALUES (in_id, in_name)
ON DUPLICATE KEY UPDATE name = in_name;
INSERT INTO details (details_id, details)
VALUES(in_id,
in_details)
ON DUPLICATE KEY UPDATE details = in_details;
COMMIT;
END$$
DELIMITER ;
With this the problem is that it cant recognize the in_ variables and i understand that that is because i need an compound statement with BEGIN END around everything but where ever i seem to put it it is something wrong with the syntax. So what is the correct syntax when i got this type of SP with in parameters that then has an transaction? (want transaction as i will add rollback onto it as well)
You are missing datatype for the in_details-parameter and you are missing the starting BEGIN
DELIMITER $$
DROP PROCEDURE IF EXISTS `info_insert_or_update`
$$
CREATE PROCEDURE `info_insert_or_update` (
in_id bigint,
in_name varchar(150),
in_details varchar(150)
)
BEGIN
START TRANSACTION;
INSERT INTO infos (id, name)
VALUES (in_id, in_name)
ON DUPLICATE KEY UPDATE name = in_name;
INSERT INTO details (details_id, details)
VALUES(in_id, in_details)
ON DUPLICATE KEY UPDATE details = in_details;
COMMIT;
END
$$
I am using a MySQL table with date ranges. These date ranges may overlap, e. g. a date range from 2019-01-01 to 2019-01-10 and a second date range from 2019-01-05 to 2019-01-15. I need the combined date range for a time calculation, in the example, it would be 2019-01-01 to 2019-01-15. I wrote a procedure that creates a temporary table with the combined results.
Some functions use this temporary table for some time calculations. These functions call the procedure to create a temporary table, if not exists. But if the temporary table already exists, I get the error “Table was locked with a READ lock and can't be updated”. If I drop the temporary table before calling the create procedure, I do not get an error. But then every time the temporary table must be created again and the query takes almost a second to complete.
How can I prevent the error without dropping the temporary table every time?
Example:
drop database if exists TempTestDB;
create database TempTestDB;
USE `TempTestDB`;
create table TestTable(
test int auto_increment not null primary key,
name varchar(45))
;
-- real table has time data
INSERT INTO TestTable (`name`) VALUES ('test1');
DROP procedure IF EXISTS `createTempTestTable`;
DELIMITER $$
USE `TempTestDB`$$
CREATE DEFINER=`riedel`#`%` PROCEDURE `createTempTestTable`()
BEGIN
-- the temp table contains merged rows of the base table
CREATE TEMPORARY TABLE IF NOT EXISTS TempTestTable select * from TestTable;
INSERT INTO TempTestTable (`name`) VALUES ('test2');
END$$
DELIMITER ;
USE `TempTestDB`;
DELIMITER $$
USE `TempTestDB`$$
CREATE FUNCTION `getTimeForUser`(user int) RETURNS INT
BEGIN
-- real function does some time calculation
declare result int;
call TempTestDB.createTempTestTable;
select count(*) from TempTestTable into result;
RETURN result;
END$$
DELIMITER ;
select TempTestDB.getTimeForUser(1) union select TempTestDB.getTimeForUser(2);drop database if exists TempTestDB;
create database TempTestDB;
USE `TempTestDB`;
create table TestTable(
test int auto_increment not null primary key,
name varchar(45))
;
-- real table has time data
INSERT INTO TestTable (`name`) VALUES ('test1');
DROP procedure IF EXISTS `createTempTestTable`;
DELIMITER $$
USE `TempTestDB`$$
CREATE DEFINER=`riedel`#`%` PROCEDURE `createTempTestTable`()
BEGIN
-- the temp table contains merged rows of the base table
CREATE TEMPORARY TABLE IF NOT EXISTS TempTestTable select * from TestTable;
INSERT INTO TempTestTable (`name`) VALUES ('test2');
END$$
DELIMITER ;
USE `TempTestDB`;
DELIMITER $$
USE `TempTestDB`$$
CREATE FUNCTION `getTimeForUser`(user int) RETURNS INT
BEGIN
-- real function does some time calculation
declare result int;
call TempTestDB.createTempTestTable;
select count(*) from TempTestTable into result;
RETURN result;
END$$
DELIMITER ;
select TempTestDB.getTimeForUser(1) union select TempTestDB.getTimeForUser(2);
Hi i am trying to create a mysql script that I can run whenever I need to update my database. The script creates a table and then executes some stored procedures.
DELIMITER $$
CREATE TABLE IF NOT EXISTS tbl_name (
col1 bigint(20) NOT NULL AUTO_INCREMENT,
col2 varchar(255) NOT NULL,
col3 varchar(64) NOT NULL,
col4 datetime DEFAULT NULL,
PRIMARY KEY (`col1 `),
UNIQUE KEY col2 (`col2`)
) ENGINE=InnoDB AUTO_INCREMENT=572 DEFAULT CHARSET=utf8$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `myproc`(IN username
VARCHAR(255))
BEGIN
DECLARE var1 VARCHAR(64);
DECLARE expirationDate DATETIME;
SET var1 = 12345;
SET expirationDate = DATE_ADD(NOW(), INTERVAL 30 SECOND);
REPLACE INTO tbl_name (col2, col3, col4) VALUES (someval, var1, expirationDate);
END$$
DELIMITER ;
When I ran the script first time, it created the table and executed the stored procedure in MySQL Workbench. When I ran the same thing second time, I got the error 1304 procedure already exists.
I looked online here about dropping the procedure and then create again. But when I entered the below command before creating the procedure, i got an error on CREATE command with code 1064.
DROP PROCEDURE IF EXISTS myproc;
CREATE DEFINER=`root`#`localhost` PROCEDURE `myproc`(IN username
VARCHAR(255))
.
.
.
I am very new to mysql and not sure how to execute the procedure if it already exists.
Any help would be appreciated.
Since you changed to DELIMITER $$ you need to use that delimiter at the end of each statement until you change it back.
DROP PROCEDURE and CREATE PROCEDURE are separate statements, and each requires its own statement delimiter.
DROP PROCEDURE IF EXISTS myproc $$
Note the delimiter at the end of the line above.
CREATE DEFINER=`root`#`localhost` PROCEDURE `myproc`(IN username
VARCHAR(255))
.
.
.
END $$
And another delimiter at the end of the whole CREATE PROCEDURE statement.
I'm trying to run a stored procedure that will insert data to the table. In in the table, there is a trigger after add that will update the sequence table(there is no sequence in MySQL DB)
This is my stored procedure:
DELIMITER $$
CREATE DEFINER=`dbName`#`%` PROCEDURE `insertGuide`(m_name varchar(45) ,m_last varchar(45) ,addres varchar(45) ,mphone int)
BEGIN
INSERT INTO `guides` (`id`, `name`, `lastName`, `address`, `phone`)
select max(id)+1, m_name, m_last, addres, mphone
from seq;
END
This is my trigger:
USE `dbName`;
DELIMITER $$
CREATE DEFINER=`dbName`#`%` TRIGGER
guidesUpdate
AFTER INSERT ON
guides
FOR EACH ROW
BEGIN
INSERT INTO seq VALUES ();
END
when I run
call insertGuide('a' ,'aa' ,'aaa' ,'12333')
it returns an error:
Error Code: 1442. Can't update table 'seq' in stored function/trigger
because it is already used by statement which invoked this stored
function/trigger.
Can I do something about it?
The best thing you can do is to eliminate this trigger entirely. If you want to have an auto-incrementing id on a table, then simply define it in the create table statement:
create table guides as (
id int not null auto_increment primary key,
. . .
);