Exit MySQL script if database exists - mysql

I have a MySQL script that I want to use only if the database doesn't exist to inject some initial demo data for development. If it does exist I just want to break out of the script. The script starts like
CREATE DATABASE IF NOT EXISTS `demo-database`;
USE `demo-database`;
Is there a way to exit here or above the create database if the database exists so that it wont run through all the table setups and inserts?

Try this. Use INFORMATION_SCHEMA.SCHEMATA to check the existence of Database
If not exists (SELECT 1
FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = 'demo-database')
CREATE DATABASE `demo-database`
.....

What I believe now is that the construct with an if/else/endif can only be used in a stored program (see also https://dev.mysql.com/doc/refman/8.0/en/if.html)
I do not have a workaround other than creating a stored procedure that contains the code. In my situation I also have code I would to execute only on a test environment. I am creating only the stored procedure on test then as well.

Related

ERROR 1146 (42S02): Table 'mysql.proc' doesn't exist while calling a stored procedure

I am using this thread -
Rename a mysql procedure
to rename a stored procedure
Here upon trying the command as shown in the answer -
UPDATE `mysql`.`proc`
SET name = '<new_proc_name>',
specific_name = '<new_proc_name>'
WHERE db = '<database>' AND
name = '<old_proc_name>';
I get the error -
ERROR 1146 (42S02): Table 'mysql.proc' doesn't exist while calling a stored procedure
Here regarding the other questions regarding mysql.proc does not exit, none address the specific problem of calling a stored procedure.
The mysql.proc table was removed in MySQL 8.0. See No more mysql.proc in MySQL 8.0
You can use information_schema.routines to get information about stored procedures. But this is a read-only view, you can't update it. So I don't think there's any simple way to rename procedures any more. You may be able to use dynamic SQL to define the procedure with the new name using this information.
EDIT:
Unfortunately, the above is not possible just in MySQL, because CREATE PROCEDURE can't be executed using PREPARE, and information_schema.routines doesn't contain all the information needed to recreate the procedure. You could do it in an external language by performing a SHOW CREATE PROCEDURE query and then replacing the name to form a new query.
Recommend avoid fiddling with any mysql table directly.
Use show create procedure old_proc_name
And then create procedure new_proc_name ....
And drop the old drop procedure old_proc_name

how to take periodically database script backup using event in mysql

I want to take database script backup every day using event in mySql ..I am new to mySql , so unable to find out exact solution..can anybody help me to do so??
Tried it using mysqldump utility but it is command promt oriented , i want it to be done through event scheduler only.
DELIMITER $$
create EVENT `Backup`
ON SCHEDULE EVERY 1 minute
STARTS '2016-02-25 17:08:06' ON COMPLETION PRESERVE ENABLE
DO
BEGIN
SET #sql_text = CONCAT("SELECT * FROM purpleaid INTO OUTFILE '/C:/Users/Admin123/Desktop/db/" , DATE_FORMAT( NOW(), '%Y%m%d') , "db.csv'" );
PREPARE s1 FROM #sql_text;
EXECUTE s1;
DEALLOCATE PREPARE s1;
END $$
DELIMITER ;
tried this , but its for single table only.I want complete database script
You can use information_schema.tables table to get list of tables within a database, and information_schema.columns table to get list of columns (just in case you want to have column names included in the backup files).
Create a cursor by getting all table names from your database
Loop through the cursor and get the table name into a variable
Construct your select ... into outfile ... statements the same way as you do in your current code, just add the table name from the variable.
Execute the prepared statement.
If you want to add the column names dynamically to the output, then combine Joe's and matt's answers from this SO topic.
UPDATE
For views, stored procedures, functions, and triggers (and tables, for that matter) the issue is that you can't really interact with show create ... statements' results within sql. You can try to recreate their definitions from their respective information_schema tables, but as far as I know, it is not possible to fully reconstruct each object just based on these tables. You need to use an external tool for that, such us mysqldump. If you want a full backup option, then you would be a lot better off, if you used an external tool, that is scheduled by the OS' task scheduler.
Since table structures and other database objects do not change that often (at least, not in production), you can use external tool to back up the structure and use the internal scheduled script to regularly back up the contents.

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).

Drop all stored procedures in MySQL or using temporary stored procedures

Is there a statement that can drop all stored procedures in MySQL?
Alternatively (if the first one is not possible), is there such thing as temporary stored procedures in MySQL? Something similar to temporary tables?
I would have thought that this would do it, but I'm open to corrections:
(EDITED to incorporate a good point provided in the comments)
delete from mysql.proc WHERE db LIKE <yourDbName>;
(As pointed out by Balmipour in the comments below, it's a good idea to specify the database.)
I think it's valid to want to drop all procedures in a given database, otherwise in a long development cycle there's a danger of obsolete procedures and functions accumulating and muddying everything up.
Since DROP PROCEDURE and DROP FUNCTION does not allow sub selects, I thought it might be possible to perform the operation through another stored procedure, but alas, MySQL does not allow stored procedures to drop other stored procedures.
I tried to trick MySQL to to this anyway by creating prepared statements and thus separating the drop call somewhat from the stored procedure, but I've had no luck.
So therefore my only contribution is this select statement which creates a list of the statements needed to drop all stored procedures and functions.
SELECT
CONCAT('DROP ',ROUTINE_TYPE,' `',ROUTINE_SCHEMA,'`.`',ROUTINE_NAME,'`;') as stmt
FROM information_schema.ROUTINES;
This seems to drop the procedures...not sure about implications though
DELETE FROM mysql.proc WHERE db = 'Test' AND type = 'PROCEDURE';
I can almost get working a piece of code to drop all stored procs, but I think MySQL isn't letting me use a LOOP or a CURSOR outside of a stored procedure.
I can write a SQL file that counts the number of stored procedures for a given schema, and I have the code to iterate through the table and drop procedures, but I can't get it to run:
SELECT COUNT(ROUTINE_NAME)
INTO #remaining
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA = SCHEMA()
AND ROUTINE_TYPE = 'FUNCTION';
kill_loop: LOOP
IF #remaining < 1 THEN
LEAVE kill_loop;
END IF;
SELECT ROUTINE_NAME
INTO #cur_func_name
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA = SCHEMA()
AND ROUTINE_TYPE = 'FUNCTION'
LIMIT 1;
DROP FUNCTION #cur_func_name;
#remaining = #remaining - 1;
END LOOP;
I use select statement to display all Drop Procedure statements of a specific database in one cell. Then copy it to query window.
SET group_concat_max_len = 4096;
SELECT GROUP_CONCAT(Procedures SEPARATOR '; ') From (SELECT CONCAT(
"DROP PROCEDURE IF EXISTS `",SPECIFIC_NAME, '`') AS Procedures
FROM information_schema.ROUTINES R WHERE R.ROUTINE_TYPE = "PROCEDURE"
AND R.ROUTINE_SCHEMA = 'my_database_name') As CopyThis;
after the select statement which creates a list of the statements needed to drop all stored procedures and functions. You can avoid the manual work of copy pasting the listed queries as follows:
mysql>SELECT
CONCAT('DROP ',ROUTINE_TYPE,' `',ROUTINE_SCHEMA,'`.`',ROUTINE_NAME,'`;') as stmt
FROM information_schema.ROUTINES into outfile '/tmp/a.txt';
mysql> source /tmp/a.txt;
#user1070300's answer seems to work, but it looks like it can drop a lot of things.
A quick DESC mysql.proc; led me to add a WHERE to my request, so as to spare already existing MySQL procedures, which I had, of course, no reason to drop.
I executed DELETE FROM mysql.proc WHERE db NOT LIKE 'mysql';
If you have several bases and want to target only one, use DELETE FROM mysql.proc WHERE db LIKE '<yourDbName>' instead;
Btw, if like me, you are completely clearing your database and need to also drop your tables, you can use this linux shell script :
mysql -Nse 'show tables' DATABASE_NAME | while read table; do mysql -e "drop table $table" DATABASE_NAME; done
(see Truncate all tables in a MySQL database in one command? for more details)
Truncate all tables in a MySQL database in one command?

MySQL multi CREATE TABLE syntax help?

I'm trying to write a MySQL script that creates several tables. I have:
CREATE TABLE `DataBase1`.`tbl_this`(
...
);
CREATE TABLE `DataBase1`.`tbl_that`(
...
);
... (14 more) ...
BUT, only the first CREATE TABLE statement is executed. I get no syntax errors. Erm, am I missing the MSSQL equivalent of GO ? What am I doing wrong here; how do I get this baby to run all the tables?
How are you executing this script?
If you are trying to run it programmatically, you should know that the MySQL API only executes one statement at a time by default. You can't string them together with semicolons and expect it to run all the statements.
You can execute each CREATE TABLE statement individually in a loop, or else you can run a script by feeding it as input to the mysql command-line client.
It's not as easy as it would seem to write a general-purpose script runner class in your application, because the full script syntax include many corner cases.
See examples of the corner cases in my answer to Loading .sql files from within PHP.
The create table syntax looks fine. Probably the tool you use to execute your SQL just executes the first statement.
try this:
use database_name;
create table a..;
create table b..;
create table c..;
Are the tables referencing (e.g. primary keys and the like) one another? Tables are created serially, so if your second table is referencing a table that is not yet created, it will fail.
How do you execute your script ?
If you do it from command line it should be something like this:
mysql -u[username] -p[password] --database DataBase1 < scriptname.sql