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)