MySQL存储过程变量作为表名连接

时间:2017-04-26 19:31:30

标签: mysql stored-procedures concat

我想在我的存储过程中执行以下查询而不执行查询,因为这会给我带来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 ;

然而,这失败了,我不知道如何解决问题。

(请注意,在示例中,我的表名中没有空格,但在我的情况下,我的表名中可能有空格)

2 个答案:

答案 0 :(得分:2)

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)

答案 1 :(得分:1)

如果需要使用必须准备的sql语句从存储过程返回结果,则可以使用中间临时表。

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工作。

需要注意的事项:

  • 临时表是特定于连接/会话的,因此如果在连接/会话(或通过调用此程序的过程)之前执行的查询使用类似myresults之类的通用名称,从全局角度来看是安全的同名;在实践/偏执中,我倾向于使用不同的guid(在使用此技术的每个过程中)作为其中生成的任何临时表的前缀。