Я написал процедуру MYSQL и в синтаксисе есть ошибка, не могу понять правильный синтаксис - PullRequest
0 голосов
/ 09 мая 2018

Процедура MYSQL будет
1. Создайте TABLE1_ARCHIVE, аналогичный TABLE1, если его там нет.
2. Вставьте значения из таблицы TABLE1 в таблицу TABLE1_ARCHIVE на основе даты
3. Удалите эти записи из TABLE1.

Ссылка на код: https://paiza.io/projects/Eq7I5YGo-lt7_gu8wpQNdg?language=mysql

CREATE PROCEDURE ARCHIVE_EVENTS ( IN f_table VARCHAR(255),
                                IN t_table VARCHAR(255),
                                IN t_ts TIMESTAMP)
BEGIN
    DECLARE c_sql VARCHAR(255);
     DECLARE i_sql VARCHAR(255);
     DECLARE d_sql VARCHAR(255);    

SET @c_sql = CONCAT(' CREATE TABLE IF NOT EXISTS ', @t_table , ' LIKE ', @f_table );
PREPARE stmt FROM  @c_sql;
EXECUTE stmt ;

SET @i_sql = CONCAT(' INSERT INTO ', @t_table, ' SELECT * FROM ', @f_table, ' WHERE `event_date` <=  ', @t_ts);
PREPARE stmt FROM  @i_sql;
EXECUTE stmt ;

COMMIT;

SET @d_sql = CONCAT(' DELETE FROM ', @f_table, ' WHERE `event_date` <= ', @t_ts);
PREPARE stmt FROM  @d_sql;
EXECUTE stmt ;
COMMIT;
END;

CALL ARCHIVE_EVENTS ('TABLE1', 'TABLE1_ARCHIVE', now());

После внесения изменений процедура выглядит следующим образом и все еще не работает:

Я получаю ошибку

ОШИБКА 1064 (42000) в строке 2: у вас ошибка в синтаксисе SQL; проверьте руководство, соответствующее вашей версии сервера MySQL, чтобы найти правильный синтаксис для использования рядом с '' в строке 3

CREATE PROCEDURE ARCHIVE_EVENTS (IN f_table VARCHAR(255),IN t_table VARCHAR(255),IN t_ts TIMESTAMP)
BEGIN
    DECLARE c_sql VARCHAR(255);
    DECLARE i_sql VARCHAR(255);
    DECLARE d_sql VARCHAR(255);    

    SET c_sql = CONCAT(' CREATE TABLE IF NOT EXISTS ', t_table , ' LIKE ', f_table);
    PREPARE stmt FROM  c_sql;
    EXECUTE stmt ;

    SET i_sql = CONCAT(' INSERT INTO ', t_table, ' SELECT * FROM ', f_table, ' WHERE `event_date` <= ', t_ts);
    PREPARE stmt FROM  i_sql;
    EXECUTE stmt ;

    COMMIT;

    SET d_sql = CONCAT(' DELETE FROM ', f_table, ' WHERE `event_date` <= ', t_ts);
    PREPARE stmt FROM  d_sql;
    EXECUTE stmt ;
    COMMIT;
END;

CALL ARCHIVE_EVENTS ('TEST', 'TEST_ARCHIVE', now());

Ответы [ 3 ]

0 голосов
/ 09 мая 2018
DROP PROCEDURE IF EXISTS ARCHIVE_EVENTS;
CREATE PROCEDURE ARCHIVE_EVENTS (IN f_table CHAR(100),IN t_table 
CHAR(100),IN t_ts TIMESTAMP)
READS SQL DATA
COMMENT 'Test'
BEGIN

SET @c_sql = CONCAT(' CREATE TABLE IF NOT EXISTS ', t_table , ' LIKE ', f_table);
PREPARE stmt FROM  @c_sql;
EXECUTE stmt ;

SET @i_sql = CONCAT(' INSERT INTO ', t_table, ' SELECT * FROM ', f_table, ' WHERE `dateTime` <= ', DATE(t_ts));
PREPARE stmt1 FROM  @i_sql;
EXECUTE stmt1 ;

COMMIT;

SET @d_sql = CONCAT(' DELETE FROM ', f_table, ' WHERE `dateTime` <= ', DATE(t_ts));
PREPARE stmt2 FROM  @d_sql;
EXECUTE stmt2 ;
COMMIT;
END;

CALL ARCHIVE_EVENTS ('TEST', 'WS_REL_TEST', now());
0 голосов
/ 10 мая 2018
CREATE PROCEDURE ARCHIVE_EVENTS (IN f_table CHAR(100),IN t_table 
CHAR(100),IN t_ts TIMESTAMP)

BEGIN

SET @c_sql = CONCAT(' CREATE TABLE IF NOT EXISTS ', t_table , ' LIKE ', f_table);

SET @i_sql = CONCAT(' INSERT INTO ', t_table, ' SELECT * FROM ', f_table, ' WHERE `event_date` <= ',char(39), t_ts,char(39));

SET @d_sql = CONCAT(' DELETE FROM ', f_table, ' WHERE `event_date` <= ',char(39), t_ts,char(39));

PREPARE stmt FROM  @c_sql;
PREPARE stmt1 FROM  @i_sql;
PREPARE stmt2 FROM  @d_sql;


EXECUTE stmt ;
EXECUTE stmt1 ;
EXECUTE stmt2 ;
COMMIT;

END;

Это рабочий код, благодаря ответам выше. Это окончательное решение для запроса, который работал для меня.

0 голосов
/ 09 мая 2018

Нетрудно отладить такую ​​процедуру, просто вставив несколько операторов select. Обратите внимание, @variables должны использоваться в подготовленных утверждениях, и вы не указали дату t_ts. И, возможно, вы не установили разделители.

    drop procedure if exists p;
    delimiter $$

    CREATE PROCEDURE p (IN f_table VARCHAR(255),IN t_table VARCHAR(255),IN t_ts TIMESTAMP)
    BEGIN

    SET @c_sql = (select CONCAT(' CREATE TABLE IF NOT EXISTS ', t_table , ' LIKE ', f_table));
    select @c_sql;

    /*PREPARE stmt FROM  @c_sql;
        EXECUTE stmt ;
         deallocate prepare stmt;
    */   
    SET @i_sql = (select CONCAT(' INSERT INTO ', t_table, ' SELECT * FROM ', f_table, ' WHERE `event_date` <= ',char(39), t_ts,char(39)));
    select @i_sql;
    /*
    PREPARE stmt FROM  @i_sql;
    EXECUTE stmt ;
    deallocate prepare stmt;

    COMMIT;
    */
    SET @d_sql = (select CONCAT(' DELETE FROM ', f_table, ' WHERE `event_date` <= ', char(39),t_ts, char(39)));
    select @d_sql;
    /*
    PREPARE stmt FROM  @d_sql;
    EXECUTE stmt ;
    deallocate prepare stmt;
    COMMIT;
    */
END $$
delimiter ;
drop table users_copy;
CALL p('users', 'users_copy', now());

Yield these statements
+---------------------------------------------------+
| @c_sql                                            |
+---------------------------------------------------+
|  CREATE TABLE IF NOT EXISTS users_copy LIKE users |
+---------------------------------------------------+
1 row in set (0.00 sec)

+-----------------------------------------------------------------------------------------+
| @i_sql                                                                                  |
+-----------------------------------------------------------------------------------------+
|  INSERT INTO users_copy SELECT * FROM users WHERE `event_date` <= '2018-05-09 19:36:54' |
+-----------------------------------------------------------------------------------------+
1 row in set (0.02 sec)

+----------------------------------------------------------------+
| @d_sql                                                         |
+----------------------------------------------------------------+
|  DELETE FROM users WHERE `event_date` <= '2018-05-09 19:36:54' |
+----------------------------------------------------------------+
1 row in set (0.04 sec)

Затем вы можете протестировать каждый из них, если хотите или раскомментировать подготовленные заявления, и позволить копировать.

...