我创建了如下程序。我正在传递表名和限制以及用户名
DELIMITER $$
DROP PROCEDURE IF EXISTS `GetPosteingang`$$
CREATE PROCEDURE `GetPosteingang`
(
IN stlimit INT,
IN tblname VARCHAR(100),
IN userId INT
)
BEGIN
DECLARE t1 VARCHAR(5000);
SET @t1 =
"SELECT msg_id,msg_from_name as fromname,msg_titel as title,msg_date as date,msg_gelesen,msg_replied,msg_nodel,'msg' as type
FROM "+@tblname+"
UNION
SELECT files_id as msg_id,from_username as fromname,files_oname as title,files_time as date,files_name as msg_gelesen,files_extension as msg_replied,files_filesize as msg_nodel,'file' as type
FROM community_files
WHERE user_id = "+@userId+"
ORDER BY date DESC
LIMIT "+@stlimit+",30";
#SET @t1 =CONCAT('SELECT * FROM ',tab_name );
PREPARE STMT FROM @t1;
EXECUTE STMT;
DEALLOCATE PREPARE STMT;
END $$
DELIMITER ;
但是当我这样称呼时,
CALL GetPosteingang('1','community_msgin8','658468');
它给了我错误,
CALL GetPosteingang('1','community_msgin8','658468') Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL' at line 1
请帮帮我。
答案 0 :(得分:3)
+
不是字符串连接运算符 - 而是使用MySQL的CONCAT()
函数;
用户定义的(会话)变量(以@
为前缀)are different到存储程序/声明的变量(没有前缀);
小心使用导致SQL注入的tblname
调用您的过程;
UNION
中的列名由第一个查询确定;以及
尽可能参数化您准备好的陈述。
因此:
CREATE PROCEDURE `GetPosteingang`
(
IN stlimit INT,
IN tblname VARCHAR(100),
IN userId INT
)
BEGIN
SET @t1 := CONCAT("
SELECT msg_id,
msg_from_name AS fromname,
msg_titel AS title,
msg_date AS date,
msg_gelesen,
msg_replied,
msg_nodel,
'msg' AS type
FROM `", REPLACE('`','``',tblname), "`
UNION
SELECT files_id,
from_username,
files_oname,
files_time,
files_name,
files_extension,
files_filesize,
'file' as type
FROM community_files
WHERE user_id = ?
ORDER BY date DESC
LIMIT ?, 30
", @t2 := userId, @t3 := stlimit;
PREPARE stmt FROM @t1;
EXECUTE stmt USING @t2, @t3;
DEALLOCATE PREPARE stmt;
END$$
然而,所有这一切都说,拥有一个变量表名称是一个强有力的指标,表明您的模式严重非规范化 - 考虑将所有这些表合并为一个表,其中的列标识了它们的差异。
答案 1 :(得分:0)
上面的代码缺少CONCAT函数的结束括号。所以它应该是这样的:
CREATE PROCEDURE `GetPosteingang`
(
IN stlimit INT,
IN tblname VARCHAR(100),
IN userId INT
)
BEGIN
SET @t1 := CONCAT("
SELECT msg_id,
msg_from_name AS fromname,
msg_titel AS title,
msg_date AS date,
msg_gelesen,
msg_replied,
msg_nodel,
'msg' AS type
FROM `", REPLACE('`','``',tblname), "`
UNION
SELECT files_id,
from_username,
files_oname,
files_time,
files_name,
files_extension,
files_filesize,
'file' as type
FROM community_files
WHERE user_id = ?
ORDER BY date DESC
LIMIT ?, 30
"), @t2 := userId, @t3 := stlimit;
PREPARE stmt FROM @t1;
EXECUTE stmt USING @t2, @t3;
DEALLOCATE PREPARE stmt;
END$$