How to get MySQL Workbench generating SQL without defining DELIMITERs? - mysql

In my model I defined some procedures. When I use the "Forward Engineering", in the generated every procedure gets a DELIMITER definition:
-- schema
CREATE DATABASE ...
CREATE TABLE foo ...
-- procedures
DELIMITER $$
...
BEGIN
...
END$$
DELIMITER ;
I need the SQL as input for the PDO#exec(...) and notice now, that the execution stops on the line of the first DELIMITER definition. But without defining delimiters it works.
How to use MySQL Workbench to generate SQL code with procedures without DELIMITER statements?

Related

SQL error when I try to ALTER TABLE in a stored procedure

I have a stored procedure designed to generate a new, 'derived' table. In this procedure I then want to add a column using ALTER TABLE. However, despite an almost identical stored procedure working fine, and despite being able to add this manually as a stored procedure to the database using MySQL Workbench, when I pass the code to the server using SOURCE (i.e. SOURCE workload.sql), I get an error 1146 (42502) 'Table 'workload._convenor_workload' doesn't exist.' (I'm doing this in Emacs as part of a org-babel block, but this is essentially just passing raw SQL to the server.)
As background, I'm in the process of migrating SQL code from a setting where I was running it raw to create my final database to one where I'd like this code to be called via triggers.
Setup: mysql Ver 8.0.16 for macos10.14 on x86_64 (MySQL Community Server - GPL)
I've tried rewriting this as a prepared statement, was unsuccessful, and have been scouring Stack Overflow. This is my first MySQL project and my reading of the documentation suggests that ALTER TABLE is a perfectly legal thing to do in a stored procedure. It's likely that I'm making a schoolboy error somewhere but at the moment I'm banging my head.
Elsewhere in my SQL, this code works in a stored procedure (ALTER TABLE function does not throw an error):
CREATE TABLE _assessment_allocations AS SELECT Assessment_ID,
IFNULL(SUM(_total_first_marking_hours),0) AS _total_first_marking_hours_sum,
GROUP_CONCAT(DISTINCT _total_first_marking_hours_needed) AS _total_first_marking_hours_needed,
GROUP_CONCAT(DISTINCT Prog_ID) AS prog_id
FROM
_marking_workload
GROUP BY Prog_ID, Assessment_ID;
ALTER TABLE _assessment_allocations
ADD COLUMN _assessment_variance DECIMAL(5,2);
However, the code that throws the error is this (specifically, the ALTER TABLE function; I've added the stored procedure code in case this is helpful). Note that this code does not throw an error when ingested by MySQL outside a stored procedure:
USE `workload`;
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `module_administration_convenor`()
-- Begin by selecting elements of the ~modules~ table
CREATE TABLE `_convenor_workload` AS
SELECT Modules.Module_Code,
Modules.Module_Name,
Modules.Module_Convenor_ID,
Modules.Module_Convenor_Share,
Modules.Student_Tally,
Modules.Additional_Hours,
Modules.Convening_Notes,
Modules.Active_Status
FROM modules;
-- Add a 'Convenor' column
ALTER TABLE `_convenor_workload` ADD COLUMN `Name` VARCHAR(255) DEFAULT 'Convenor';
\* Other stuff *\
END$$
DELIMITER ;
My aim is to avoid throwing this error. I'd like to get this stored procedure actually stored! (Just like the previous stored procedure that does much the same and does not throw an error.) I'm aware that there are some back-tick and style differences between the working and non-working code, but I'm guessing these aren't super important.
As I said, I have a strong suspicion that I'm overlooking something obvious here...
As mentioned by Solarflare in the comments, you are missing a begin so the alter table is executing as a separate action. If you wrap it with begin and end then it treats all the code as the stored procedure.
USE `workload`;
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `module_administration_convenor`()
Begin
-- Begin by selecting elements of the ~modules~ table
CREATE TABLE `_convenor_workload` AS
SELECT Modules.Module_Code,
Modules.Module_Name,
Modules.Module_Convenor_ID,
Modules.Module_Convenor_Share,
Modules.Student_Tally,
Modules.Additional_Hours,
Modules.Convening_Notes,
Modules.Active_Status
FROM modules;
-- Add a 'Convenor' column
ALTER TABLE `_convenor_workload` ADD COLUMN `Name` VARCHAR(255) DEFAULT 'Convenor';
END
$$
DELIMITER ;

mysql stored procedure and functions syntax errors

I'm working in mysql workbench 8.0.11 and having problems creating stored procedures and also functions. Just to be clear, I am running this in mysql via the mysql workbench. I am not using any other program at all.
I'm trying to create a new stored procedure. I keep getting a syntax error: "delimiter" is no valid input at this position, expecting: CREATE.
I have checked the mysql website to make sure my syntax is correct, and it matches. Another thing to note is that I've tried starting the stored procedure with use accounting; (the db I'm working with) and I get the same error, except that "use" takes the place of "delimiter". So, I'm not sure it has anything to do with the delimiter keyword itself. Is there some setting in mysql workbench that I can set to get this straightened out? Also, I get the same exact syntax error when trying to create a function.
I have tried creating both a stored procedure and a function without using the delimiter keyword, or the use keyword, and when I hit the apply key mysql crashes.
Here is my code:
delimiter $$
create procedure 'add_expense_category' (id int, name varchar(20))
begin
insert into expense_categories(expense_category_id, expense_category)
values(id, name);
end $$
delimiter ;
Anyone have any ideas on how to solve this? Settings to change? Anything?
Thanks!
try this
delimiter $$
create procedure `add_expense_category` (id int, name varchar(20))
begin
insert into expense_categories(expense_category_id, expense_category)
values(id, name);
end $$
delimiter ;

Why semi-colon is not required after use database statement in MySQL?

Kindly help me to understand the reason to put delimiter (;) after every MySQL statement. Can we change default delimiter to some other character(like | ). And why it is not required to put ; after USE database command?
You change the delimiter with the delimiter statement. eg
delimiter //, then all your statements will need to be terminated with a //
this is necessary when defining stored procedures or triggers that require compound statements.
You can (obviously) change it back to a semi-colon with delimiter ;
use doesn't require a delimiter (in the command line client) because it's a cli command, not an sql command. (at least, according to this bug report)

Create a stored procedure only if the procedure does not exist in mysql

In SQL Server I am able to achieve this using dynamic sql string, but now I need to do the same thing for mysql but am getting nowhere, is there any way to achive this
IF NOT EXISTS (SELECT 1 FROM mysql.proc p WHERE NAME = 'stored_proc_name')
BEGIN
DELIMITER $$
CREATE PROCEDURE justATest()
BEGIN
-- some SP logic here
END$$
END
I am storing the whole sql as a string inside a database column and execute the statement using a prepared statement Execute inside another stored procedure.
IF NOT EXISTS(SELECT 1 FROM mysql.proc p WHERE db = 'db_name' AND name = 'stored_proc_name') THEN
....
taken from
Older Post
Control statements like if then else are only allowed inside Stored Procedures in MySQL (unfortunately). There are usually ways around this, but it depends why you are conditionally creating the sproc.
E.g. If you're trying to avoid errors when running build scripts because sprocs already exist then you can use a conditional drop statement prior to your create like this:
DROP PROCEDURE IF EXISTS justATest;
CREATE PROCEDURE justATest()
BEGIN
-- enter code here
END;
This will ensure the any changed code gets run (rather than skipped).

Can I create a trigger in mysql schema in phpmyadming

When I ran the same query in different databases, it works successfully. But in mysql schem it gives error:
#trigger can not be created on system table
My query is:
delimiter //
CREATE TRIGGER `invite` AFTER INSERT ON `Invite_page`
FOR EACH ROW BEGIN
Insert into userpost(userid,url,title,preview,sentiment,time) values(NEW.userid,NEW.url,NEW.title,NEW.preview,NEW.sentiment,NEW.time);
Insert into urlcontent(userid,url,title,preview,sentiment,time) values(NEW.userid,NEW.url,NEW.title,NEW.preview,NEW.sentiment,NEW.time);
END
//
delimiter ;
If I can't, then how can I solve this instead?
UPDATE:
actual error:
#1465 - Triggers can not be created on system tables
Try this
DELIMITER $$
CREATE TRIGGER `invite` AFTER INSERT ON `Invite_page`
FOR EACH ROW
BEGIN
Insert into userpost(userid,url,title,preview,sentiment,time) values(NEW.userid,NEW.url,NEW.title,NEW.preview,NEW.sentiment,NEW.time);
Insert into urlcontent(userid,url,title,preview,sentiment,time) values(NEW.userid,NEW.url,NEW.title,NEW.preview,NEW.sentiment,NEW.time);
END$$
DELIMITER ;
Under the "Restrictions for triggers" section in http://dev.mysql.com/doc/refman/5.5/en/stored-program-restrictions.html you can read:
Triggers are not permitted on tables in the mysql database.
BTW, are you using the mysql schema to store data? This is (usually) a very bad idea and probably you need to rethink your setup.