MySQL 存储过程变量作为 Table 名称连接
MySQL Stored Procedure Variable as Table Name concatenated
我有以下查询,我想在我的存储过程中执行而不准备查询,因为这给我 OUT 传回参数带来了问题。
DELIMITER //
CREATE PROCEDURE Test (
IN CID BIGINT(20),
IN IDs LONGTEXT
)
BEGIN
#EXECUTE UNDERNEATH QUERY
SELECT * FROM CONCAT('Part1_OfTableName', CID); #CID IS CustomerID
END //
DELIMITER ;
然而,这失败了,我不知道如何解决这个问题。
(请注意,在示例中,我的 table 名称中没有 space,但是在我的情况下,我可能有 space 在我的 table 名字里)
如果您需要 return 来自使用必须准备的 sql 语句的存储过程的结果,您可以使用中间临时 table.
BEGIN
CREATE TEMPORARY TABLE `myresults` blah blah....;
//construct and prepare select you would've used, but start it with an insert like so...
// INSERT INTO `myresults` SELECT ....
// Execute the prepared query
SELECT * FROM `myresults`;
DROP TEMPORARY TABLE `myresults`;
END
...至少我很确定这种技术曾经有效;在过去的几年里,我一直在使用 MSSQL。
注意事项:
- 临时 table 是 connection/session 特定的,因此从全局角度来看,使用像
myresults
这样的通用名称是安全的,但如果查询较早地在 connection/session(或通过调用此程序的过程)使用相同的名称;在 practice/paranoia 中,我倾向于使用不同的 guid(在使用此技术的每个过程中)作为其中生成的任何临时 table 的前缀。
PREPARE
应该不会影响您成功设置 OUT
程序参数的能力
SET DELIMITER //
CREATE PROCEDURE test(IN cid INT, IN ids TEXT, OUT out_int INT)
BEGIN
SET @sql = CONCAT('SELECT * FROM `table_', cid, '`', CASE WHEN ids IS NULL THEN '' ELSE CONCAT(' WHERE id IN( ', ids, ')') END);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET out_int = 1;
END//
SET DELIMITER ;
示例用法:
mysql> CALL test(1, '2,3', @out_int);
+------+
| id |
+------+
| 2 |
| 3 |
+------+
2 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @out_int;
+----------+
| @out_int |
+----------+
| 1 |
+----------+
1 row in set (0.00 sec)
我有以下查询,我想在我的存储过程中执行而不准备查询,因为这给我 OUT 传回参数带来了问题。
DELIMITER //
CREATE PROCEDURE Test (
IN CID BIGINT(20),
IN IDs LONGTEXT
)
BEGIN
#EXECUTE UNDERNEATH QUERY
SELECT * FROM CONCAT('Part1_OfTableName', CID); #CID IS CustomerID
END //
DELIMITER ;
然而,这失败了,我不知道如何解决这个问题。
(请注意,在示例中,我的 table 名称中没有 space,但是在我的情况下,我可能有 space 在我的 table 名字里)
如果您需要 return 来自使用必须准备的 sql 语句的存储过程的结果,您可以使用中间临时 table.
BEGIN
CREATE TEMPORARY TABLE `myresults` blah blah....;
//construct and prepare select you would've used, but start it with an insert like so...
// INSERT INTO `myresults` SELECT ....
// Execute the prepared query
SELECT * FROM `myresults`;
DROP TEMPORARY TABLE `myresults`;
END
...至少我很确定这种技术曾经有效;在过去的几年里,我一直在使用 MSSQL。
注意事项:
- 临时 table 是 connection/session 特定的,因此从全局角度来看,使用像
myresults
这样的通用名称是安全的,但如果查询较早地在 connection/session(或通过调用此程序的过程)使用相同的名称;在 practice/paranoia 中,我倾向于使用不同的 guid(在使用此技术的每个过程中)作为其中生成的任何临时 table 的前缀。
PREPARE
应该不会影响您成功设置 OUT
程序参数的能力
SET DELIMITER //
CREATE PROCEDURE test(IN cid INT, IN ids TEXT, OUT out_int INT)
BEGIN
SET @sql = CONCAT('SELECT * FROM `table_', cid, '`', CASE WHEN ids IS NULL THEN '' ELSE CONCAT(' WHERE id IN( ', ids, ')') END);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET out_int = 1;
END//
SET DELIMITER ;
示例用法:
mysql> CALL test(1, '2,3', @out_int); +------+ | id | +------+ | 2 | | 3 | +------+ 2 rows in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) mysql> SELECT @out_int; +----------+ | @out_int | +----------+ | 1 | +----------+ 1 row in set (0.00 sec)