Is it possible to run Stored Procedures on MySQL 4.x? Yes and no – of course the feature is not available directly in MySQL 4.x, but if you have a MySQL 5.x server with the FEDERATED Storage Engine available, it’s no big deal to accomplish that.
Here’s how it works – we start with this on a MySQL 4.x server:
mysql> SELECT version(); +-----------+ | version() | +-----------+ | 4.0.18-nt | +-----------+ 1 row in set (0.03 sec) mysql> SHOW CREATE TABLE tt \G *************************** 1. row *************************** Table: tt Create Table: CREATE TABLE `tt` ( `id` int(10) unsigned NOT NULL auto_increment, `val` int(10) unsigned NOT NULL default '0', `ts` timestamp(14) NOT NULL, PRIMARY KEY (`id`) ) TYPE=MyISAM 1 row in set (0.03 sec) mysql> SELECT * FROM tt; Empty set (0.03 sec)
The next step is to create a FEDERATED table with the same definition on a MySQL 5.x server:
mysql> SELECT version(); +-----------------+ | version() | +-----------------+ | 5.1.13-beta-log | +-----------------+ 1 row in set (0.00 sec) mysql> CREATE TABLE `tt` ( -> `id` int(10) unsigned NOT NULL auto_increment, -> `val` int(10) unsigned NOT NULL default '0', -> `ts` timestamp(14) NOT NULL, -> PRIMARY KEY (`id`) -> ) ENGINE=FEDERATED -> CONNECTION='mysql://user:password@remote_4x_server/database/tt'; Query OK, 0 rows affected (0.72 sec)
All we need to do is to create a Stored Procedure on the MySQL 5.x server which accesses the tt FEDERATED table:
DROP PROCEDURE IF EXISTS fill_tt; DELIMITER // CREATE PROCEDURE fill_tt (_rows INT) BEGIN DECLARE cnt INT DEFAULT 0; WHILE cnt < _rows DO INSERT INTO tt (val) VALUES (FLOOR(RAND()*1000)); SET cnt := cnt + 1; END WHILE; END // DELIMITER ;
Now it’s simple to insert a few rows using this Stored Procedure:
mysql> CALL fill_tt(10); Query OK, 1 row affected (0.69 sec) mysql> SELECT * FROM tt; +----+-----+---------------------+ | id | val | ts | +----+-----+---------------------+ | 1 | 952 | 2006-11-23 01:57:54 | | 2 | 591 | 2006-11-23 01:57:54 | | 3 | 98 | 2006-11-23 01:57:54 | | 4 | 718 | 2006-11-23 01:57:54 | | 5 | 295 | 2006-11-23 01:57:54 | | 6 | 324 | 2006-11-23 01:57:54 | | 7 | 733 | 2006-11-23 01:57:54 | | 8 | 693 | 2006-11-23 01:57:54 | | 9 | 269 | 2006-11-23 01:57:54 | | 10 | 264 | 2006-11-23 01:57:54 | +----+-----+---------------------+ 10 rows in set (0.09 sec)
Running the same query on the MySQL 4.x server proves that the records have been properly inserted:
mysql> SELECT version(); +-----------+ | version() | +-----------+ | 4.0.18-nt | +-----------+ 1 row in set (0.03 sec) mysql> SELECT * FROM tt; +----+-----+----------------+ | id | val | ts | +----+-----+----------------+ | 1 | 952 | 20061123015754 | | 2 | 591 | 20061123015754 | | 3 | 98 | 20061123015754 | | 4 | 718 | 20061123015754 | | 5 | 295 | 20061123015754 | | 6 | 324 | 20061123015754 | | 7 | 733 | 20061123015754 | | 8 | 693 | 20061123015754 | | 9 | 269 | 20061123015754 | | 10 | 264 | 20061123015754 | +----+-----+----------------+ 10 rows in set (0.03 sec)
Great idea. I suppose this could also be done via replication? Maybe, triggers can be replicated too… but it’s just an idea, I don’t really know if it is possible in practice.