views:

354

answers:

1

Hi,

I'm very new to MySQL and I have a stored procedure that I'd like to add to several legacy databases. I'm using SQLyog and I would like to loop through each database on the connection and if it matches 'application_%' (databases are called application_clientName, there are dozens) to run the stored procedure.

A script I can save and run through SQLyog would be ideal.

I'm kind of looking to loop through all the databases in SHOW DATABASES and run a statment if their name is LIKE 'application_%'. The statment will create a generic stored procedure in that database.

Thanks, Tim

A: 

Okay, it looks like the SCHEMATA table in the information_scheme database contains a list of all databases. Thus, in order to get a list of all the databases you want to run the procedure on, you can do:

SELECT schema_name FROM information_schema.schemata
WHERE schema_name LIKE '%application_';

The next step is to work this into some kind of procedure. Unfortunately, MySQL doesn't do well with executing dynamically generated SQL if it involves creating procedures. Thus, the purely-SQL version I came up with is a bit messy. It comes down to first creating the 'generator' procedure, then calling it, and finally executing the result of the generator:

delimiter //
DROP PROCEDURE IF EXISTS create_procedures;
CREATE PROCEDURE create_procedures()
BEGIN
    DECLARE done INT DEFAULT 0;
    DECLARE db VARCHAR(255);
    DECLARE appDBs CURSOR FOR SELECT schema_name FROM information_schema.schemata WHERE schema_name LIKE 'application_%';
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    SET @procName = "simpleproc"; -- Change this to your proc name

    SET @output = "delimiter //";

    OPEN appDBs;
    REPEAT
        FETCH appDBs INTO db;
        IF NOT done THEN
            -- Replace this procedure declaration with your procedure.
            -- Make sure to keep the ',db,' syntax there.
            -- You should really only have to change the parameters
            -- and the stuff between the BEGIN and END clauses.
            SET @output = CONCAT(@output,'
    DROP PROCEDURE IF EXISTS ',db,'.',@procName,'//
    CREATE PROCEDURE ',db,'.',@procName,'()
        BEGIN
            SELECT 1;
        END//');

        END IF;
    UNTIL done END REPEAT;

    CLOSE appDBs;

    SET @output = CONCAT(@output,'\ndelimiter ;');

    SELECT @output AS procs;
END//
delimiter ;

After this procedure is generated, call the procedure:

CALL create_procedures();

This will output a single column that contains the SQL necessary to create procedures for all the application_% tables. Select the entire column (it'll be rather long), and execute it as a new SQL query.

I've never used SQLyog, but if that doesn't work properly, then you may need to use MySQL's command line interface. First, generate a file input.sql containing:

CALL create_procedures();

Then execute the following commands:

mysql -u <username> -p --database=<dbname> -N -r -B < input.sql > proc.sql
mysql -u <username> -p --database=<dbname> < proc.sql

changing <username> and <dbname> to appropriate values (<dbname> can be any database you have permission to access). If you don't run into any errors, then you should have stored procedures defined for every database.

cmptrgeekken
Thanks very much. I got this working in SQLyog and it's saved me a whole load of time.
BigTommy79