如何检查 MariaDB 语法错误(错误代码 1064)?
How to check a MariaDB syntax error (Error Code 1064)?
我在 MariaDB 10 上有 2 个简单的存储过程,以便从我的 table 中自动清除数据。
第一个从简单的 table 中读取配置项并将该数据传递给第二个,第二个从物理上删除记录。
在测试期间一切正常,但现在我收到错误 "错误代码:1064。您的 SQL 语法有错误;请查看与您的 MariaDB 服务器版本对应的手册以确保正确在第 1 行 0,052 秒 'NULL' 附近使用的语法,我不知道为什么。
程序如下:
CREATE DEFINER=`root`@`10.135.15.%` PROCEDURE `clean_table_checker`()
BEGIN
DECLARE TMP_TIME_AGO INT(11);
DECLARE TMP_ID INT(11);
DECLARE TMP_RETENTION_SECS INT(11);
DECLARE TMP_DBNAME VARCHAR(45);
DECLARE TMP_TABLENAME VARCHAR(45);
DECLARE TMP_TS_FIELD VARCHAR(45);
DECLARE TMP_LASTUPDATE INT(11);
DECLARE TMP_RETENTION INT(4);
DECLARE DONE INT DEFAULT 0;
DECLARE get_tables CURSOR FOR SELECT `id`, `dbname`, `tablename`, `ts_field`, `lastupdate`, `retention` FROM management.clean_table;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN get_tables;
loop_cursor_ptr: LOOP
IF DONE THEN
LEAVE loop_cursor_ptr;
END IF;
FETCH get_tables INTO TMP_ID, TMP_DBNAME, TMP_TABLENAME, TMP_TS_FIELD, TMP_LASTUPDATE, TMP_RETENTION;
SET TMP_TIME_AGO = UNIX_TIMESTAMP(NOW()) - TMP_LASTUPDATE;
SET TMP_RETENTION_SECS = TMP_RETENTION * 86400;
IF TMP_LASTUPDATE is NULL THEN
SET @SQL = CONCAT('UPDATE management.clean_table SET `lastupdate`=',UNIX_TIMESTAMP(NOW()),' WHERE `id`=',TMP_ID,';');
ELSEIF (TMP_TIME_AGO > TMP_RETENTION_SECS) THEN
CALL clean_table_proc(TMP_DBNAME, TMP_TABLENAME, TMP_TS_FIELD, TMP_RETENTION_SECS);
SET @SQL = CONCAT('UPDATE management.clean_table SET `lastupdate`=',UNIX_TIMESTAMP(NOW()),' WHERE `id`=',TMP_ID,';');
END IF;
PREPARE STMT FROM @SQL;
EXECUTE STMT;
DEALLOCATE PREPARE STMT;
END LOOP loop_cursor_ptr;
CLOSE get_tables;
END
有什么想法吗?建议?
提前致谢
如果您的条件 (TMP_LASTUPDATE is NULL
、TMP_TIME_AGO > TMP_RETENTION_SECS
) 都不成立,则 @SQL
的值未设置,因此 NULL
。然后,您将尝试从 NULL
值准备一个语句,这就是您看到错误的原因。您需要添加一个关于是否需要执行查询的测试,例如:
SET @SQL = ''
IF TMP_LASTUPDATE is NULL THEN
SET @SQL = CONCAT('UPDATE management.clean_table SET `lastupdate`=',UNIX_TIMESTAMP(NOW()),' WHERE `id`=',TMP_ID,';');
ELSEIF (TMP_TIME_AGO > TMP_RETENTION_SECS) THEN
CALL clean_table_proc(TMP_DBNAME, TMP_TABLENAME, TMP_TS_FIELD, TMP_RETENTION_SECS);
SET @SQL = CONCAT('UPDATE management.clean_table SET `lastupdate`=',UNIX_TIMESTAMP(NOW()),' WHERE `id`=',TMP_ID,';');
END IF;
IF @SQL != '' THEN
PREPARE STMT FROM @SQL;
EXECUTE STMT;
DEALLOCATE PREPARE STMT;
END IF;
我在 MariaDB 10 上有 2 个简单的存储过程,以便从我的 table 中自动清除数据。 第一个从简单的 table 中读取配置项并将该数据传递给第二个,第二个从物理上删除记录。 在测试期间一切正常,但现在我收到错误 "错误代码:1064。您的 SQL 语法有错误;请查看与您的 MariaDB 服务器版本对应的手册以确保正确在第 1 行 0,052 秒 'NULL' 附近使用的语法,我不知道为什么。
程序如下:
CREATE DEFINER=`root`@`10.135.15.%` PROCEDURE `clean_table_checker`()
BEGIN
DECLARE TMP_TIME_AGO INT(11);
DECLARE TMP_ID INT(11);
DECLARE TMP_RETENTION_SECS INT(11);
DECLARE TMP_DBNAME VARCHAR(45);
DECLARE TMP_TABLENAME VARCHAR(45);
DECLARE TMP_TS_FIELD VARCHAR(45);
DECLARE TMP_LASTUPDATE INT(11);
DECLARE TMP_RETENTION INT(4);
DECLARE DONE INT DEFAULT 0;
DECLARE get_tables CURSOR FOR SELECT `id`, `dbname`, `tablename`, `ts_field`, `lastupdate`, `retention` FROM management.clean_table;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN get_tables;
loop_cursor_ptr: LOOP
IF DONE THEN
LEAVE loop_cursor_ptr;
END IF;
FETCH get_tables INTO TMP_ID, TMP_DBNAME, TMP_TABLENAME, TMP_TS_FIELD, TMP_LASTUPDATE, TMP_RETENTION;
SET TMP_TIME_AGO = UNIX_TIMESTAMP(NOW()) - TMP_LASTUPDATE;
SET TMP_RETENTION_SECS = TMP_RETENTION * 86400;
IF TMP_LASTUPDATE is NULL THEN
SET @SQL = CONCAT('UPDATE management.clean_table SET `lastupdate`=',UNIX_TIMESTAMP(NOW()),' WHERE `id`=',TMP_ID,';');
ELSEIF (TMP_TIME_AGO > TMP_RETENTION_SECS) THEN
CALL clean_table_proc(TMP_DBNAME, TMP_TABLENAME, TMP_TS_FIELD, TMP_RETENTION_SECS);
SET @SQL = CONCAT('UPDATE management.clean_table SET `lastupdate`=',UNIX_TIMESTAMP(NOW()),' WHERE `id`=',TMP_ID,';');
END IF;
PREPARE STMT FROM @SQL;
EXECUTE STMT;
DEALLOCATE PREPARE STMT;
END LOOP loop_cursor_ptr;
CLOSE get_tables;
END
有什么想法吗?建议?
提前致谢
如果您的条件 (TMP_LASTUPDATE is NULL
、TMP_TIME_AGO > TMP_RETENTION_SECS
) 都不成立,则 @SQL
的值未设置,因此 NULL
。然后,您将尝试从 NULL
值准备一个语句,这就是您看到错误的原因。您需要添加一个关于是否需要执行查询的测试,例如:
SET @SQL = ''
IF TMP_LASTUPDATE is NULL THEN
SET @SQL = CONCAT('UPDATE management.clean_table SET `lastupdate`=',UNIX_TIMESTAMP(NOW()),' WHERE `id`=',TMP_ID,';');
ELSEIF (TMP_TIME_AGO > TMP_RETENTION_SECS) THEN
CALL clean_table_proc(TMP_DBNAME, TMP_TABLENAME, TMP_TS_FIELD, TMP_RETENTION_SECS);
SET @SQL = CONCAT('UPDATE management.clean_table SET `lastupdate`=',UNIX_TIMESTAMP(NOW()),' WHERE `id`=',TMP_ID,';');
END IF;
IF @SQL != '' THEN
PREPARE STMT FROM @SQL;
EXECUTE STMT;
DEALLOCATE PREPARE STMT;
END IF;