【发布时间】:2017-12-09 10:28:58
【问题描述】:
我正在编写一个程序,一旦我尝试使用准备好的语句使其动态化,它就会失败。包含在准备好的字符串中的语句确实在准备好的语法之外独立工作。
附加信息:
- period_start() 和 period_end() 函数返回经过格式化并确认可以工作的日期
- 当任何 WHERE 子句参数单独隔离时,即使在准备好的语句字符串中,该过程也会运行
- 传递给 prepare stmt 的字符串可以在准备之外自行运行
目标:使用 WHERE 子句中的多个 AND 声明来执行准备好的语句。
当前代码:
DROP PROCEDURE IF EXISTS count_sessions_in_period;
DELIMITER //
CREATE PROCEDURE `count_sessions_in_period` (IN period INT)
BEGIN
SET @prepare_stmt = CONCAT("INSERT INTO 2017_p",period," (total_sessions,user_id,employee_name,manager_id)
SELECT @total_in_period := COUNT(DISTINCT m_s.class_id), m_u.uid, m_am.employee_name, m_u.manager_id
FROM m.sessions m_s
INNER JOIN m.assigned_employee m_am
ON m_s.sid = m_am.sid
INNER JOIN m.users m_u
ON m_am.employee_email = m_u.email
WHERE m_s.type = 'SESSIONS' AND m_s.date BETWEEN period_start(",period,") AND period_end(",period,") AND attended_status NOT LIKE '%cancelled%' AND attended_status NOT LIKE '%alert%'
GROUP BY m_u.uid
ON DUPLICATE KEY UPDATE total_sessions=@total_in_period");
PREPARE stmt FROM @prepare_stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
#######################################################################
CALL count_sessions_in_period(1);
收到的错误是,“您的 SQL 语法有错误;请查看与您的 MySQL 服务器版本相对应的手册,在第 8 行的“%alert%”附近找到正确的语法”
请记住,我已尝试转义所有引号并将它们全部设为单引号或双引号。
【问题讨论】:
-
也许对我来说还为时过早,但我看不到任何参数或理由让这个查询甚至准备好/动态。 ...并且根据 Notepad++,您的查询长度为 553(包括空格/换行符)!
-
本例中最初的准备是没有原因的。我简化了它,但我可以添加复杂性,但我在 CONCAT() 中添加了用于演示目的。不过,这确实与问题无关。
-
啊,我看到长度无关紧要,类似名称的变量的声明让我失望。你所说的“失败”到底是什么意思?是出现错误,还是只是数据没有按照您的预期更新?
-
如果您收到错误消息,请始终添加错误消息。我的第一个猜测:ansi 模式。尝试使用
'而不是"。 -
错误信息略有不同;我会添加它。它似乎指出了引号的问题,所以我尝试了两种方式。我将它们全部转义并使用了单引号,但请记住,如果您仅消除每个 AND 并仅使用单个 WHERE 限定符,查询就会运行。
标签: mysql prepared-statement where-clause