简体   繁体   中英

MySQL Stored Procedure Variable as Table Name concatenated

I have the following query I want to execute in my stored procedure WITHOUT PREPARING the query, since this gives me problems with OUT to pass back parameters.

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 ;

However, this fails and I don't know how to fix the problem.

(Note that in the example I have no spaces in my table name, however in my situation I might have a space in my table name though)

PREPARE should have no bearing on your ability to successfully set OUT parameters of your procedure

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 ;

Sample usage:

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)

If you need to return results from a stored procedure using sql statement that must be prepared, you can use an intermediate temp 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

...at least I am pretty sure this technique used to work; I've been working more in MSSQL the last couple years.

Something to note:

  • Temporary tables are connection/session specific, so while safe from a global perspective using a generic name like myresults can be problematic if queries executed earlier on the connection/session (or by a procedure calling this one) use the same name; in practice/paranoia, I tended to use a different guid (in each procedure using this technique) as a prefix for any temporary tables generated within it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM