复制数据的存储过程

时间:2015-03-06 09:14:55

标签: mysql stored-procedures

我对在MySQL中创建过程和触发器都很陌生,但在过去的几天里一直在努力解决这个问题,而且它根本行不通。我从Mysql获得的错误消息对我不再有帮助。

所以我正在尝试创建一个程序,我需要在更新后运行它。我将进行任何更新并将新数据存储在另一个数据库中的动态创建表中。 这是:

CREATE PROCEDURE get_price_storage_table (IN market_id INT(11), OUT tablename VARCHAR(50))
            BEGIN
                SET @NUMBER     = CEILING(market_id / 100000) * 100000;
                SET tablename   = CONCAT('price_',@NUMBER);
                SET @SQL = CONCAT('CREATE TABLE IF NOT EXISTS data.',tablename,'(
                                    `pk_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
                                    `fk_market_id` INT(11) UNSIGNED NOT NULL,
                                    `fk_outcome_type_id` MEDIUMINT(8) UNSIGNED NOT NULL,
                                    `price` DOUBLE NOT NULL,
                                    `status` ENUM(\'enabled\',\'disabled\') NOT NULL,
                                    `created` DATETIME NOT NULL,
                                    PRIMARY KEY (`pk_id`)
                                    ) ENGINE=InnoDB DEFAULT CHARSET=utf8')');
                PREPARE stmt FROM @SQL;
                EXECUTE stmt;
                DEALLOCATE PREPARE stmt;
            END;

这需要在更新后触发,其中SQL如下:

CREATE TRIGGER copy_price_data AFTER UPDATE ON price
        FOR EACH ROW
            BEGIN
                IF NEW.updated <> OLD.updated THEN
                    SET @market_id = NEW.fk_market_id;
                    SET @tablename = NULL;
                    CALL create_price_storage_table(@market_id, @tablename);
                    SELECT @tablename;
                    SET @SQL = CONCAT(
                    'INSERT INTO ',
                    @tablename,
                    ' (`fk_market_id`, `fk_outcome_type_id`, `price`, `status`, `created`) VALUES (NEW.fk_market_id, NEW.fk_outcome_type_id, NEW.price, NEW.status, NOW())');
                    PREPARE stmt FROM @SQL;
                    EXECUTE stmt;
                    DEALLOCATE PREPARE stmt;
                END IF;
            END;

尝试创建过程时,我从MySQL收到以下错误消息:

CREATE PROCEDURE get_price_storage_table (IN market_id INT(11), OUT tablename VARCHAR(50))
        BEGIN
            SET @NUMBER     = CEILING(market_id / 100000) * 100000;
  

MySQL returnerede:Dokumentation 1064 - 您的SQL中有错误   句法;查看与MySQL服务器版本对应的手册   在'第3行'附近使用正确的语法

我希望有更多了解的人能指出我正确的方向。感谢。

2 个答案:

答案 0 :(得分:1)

变化:

CREATE PROCEDURE get_price_storage_table (IN market_id INT(11), OUT tablename VARCHAR(50))
BEGIN
    SET @NUMBER     = CEILING(market_id / 100000) * 100000;
    SET tablename   = CONCAT('price_',@NUMBER);
    SET @SQL = CONCAT('CREATE TABLE IF NOT EXISTS data.',tablename,'(
                        `pk_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
                        `fk_market_id` INT(11) UNSIGNED NOT NULL,
                        `fk_outcome_type_id` MEDIUMINT(8) UNSIGNED NOT NULL,
                        `price` DOUBLE NOT NULL,
                        `status` ENUM(\'enabled\',\'disabled\') NOT NULL,
                        `created` DATETIME NOT NULL,
                        PRIMARY KEY (`pk_id`)
                        ) ENGINE=InnoDB DEFAULT CHARSET=utf8')');
    PREPARE stmt FROM @SQL;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END;

人:

CREATE PROCEDURE `get_price_storage_table`(`market_id` INT UNSIGNED, OUT `tablename` VARCHAR(50))
BEGIN
    DECLARE `NUMBER` INT UNSIGNED;
    SET `NUMBER`     := CEILING(`market_id` / 100000) * 100000;
    SET `tablename`  := CONCAT('`price_', NUMBER, '`');
    SET @`SQL`       := CONCAT('CREATE TABLE IF NOT EXISTS ', tablename, '(
                        `pk_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
                        `fk_market_id` INT(11) UNSIGNED NOT NULL,
                        `fk_outcome_type_id` MEDIUMINT(8) UNSIGNED NOT NULL,
                        `price` DOUBLE NOT NULL,
                        `status` ENUM(\'enabled\',\'disabled\') NOT NULL,
                        `created` DATETIME NOT NULL,
                        PRIMARY KEY (`pk_id`)
                        ) ENGINE=InnoDB DEFAULT CHARSET=utf8');
                     -- ) ENGINE=InnoDB DEFAULT CHARSET=utf8')');
    PREPARE `stmt` FROM @`SQL`;
    EXECUTE `stmt`;
    DEALLOCATE PREPARE `stmt`;
END//

示例:

mysql> DROP PROCEDURE IF EXISTS `get_price_storage_table`;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> DELIMITER //

mysql> CREATE PROCEDURE `get_price_storage_table`(`market_id` INT UNSIGNED, OUT `tablename` VARCHAR(50))
    -> BEGIN
    ->     DECLARE `NUMBER` INT UNSIGNED;
    ->     SET `NUMBER`     := CEILING(`market_id` / 100000) * 100000;
    ->     SET `tablename`  := CONCAT('`price_', NUMBER, '`');
    ->     SET @`SQL`       := CONCAT('CREATE TABLE IF NOT EXISTS ', tablename, '(
     >                         `pk_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
     >                         `fk_market_id` INT(11) UNSIGNED NOT NULL,
     >                         `fk_outcome_type_id` MEDIUMINT(8) UNSIGNED NOT NULL,
     >                         `price` DOUBLE NOT NULL,
     >                         `status` ENUM(\'enabled\',\'disabled\') NOT NULL,
     >                         `created` DATETIME NOT NULL,
     >                         PRIMARY KEY (`pk_id`)
     >                         ) ENGINE=InnoDB DEFAULT CHARSET=utf8');
    ->     PREPARE `stmt` FROM @`SQL`;
    ->     EXECUTE `stmt`;
    ->     DEALLOCATE PREPARE `stmt`;
    -> END//
Query OK, 0 rows affected (0.00 sec)

mysql> DELIMITER ;

mysql> CALL `get_price_storage_table`(1, @`tablename`);
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @`tablename`;
+----------------+
| @`tablename`   |
+----------------+
| `price_100000` |
+----------------+
1 row in set (0.00 sec)

mysql> SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| price_100000   |
+----------------+
1 row in set (0.00 sec)

答案 1 :(得分:0)

语法错误应位于错误消息中报告的位置的左侧(或上方),因为报告的位置是第一个混淆MySQL的地方。
在您的情况下,这是;
它完成了你的CREATE PROCEDURE语句,但是MySQL期望更多,就像END一样。 当过程/触发器/函数由多个语句组成时,必须使用不同的分隔符声明它们。

试试这样:

DELIMITER $$
CREATE PROCEDURE whatever()
BEGIN
SELECT 'whatever';
SELECT 'another';
END $$
DELIMITER ;