MySQL存储过程 - 将SELECT作为参数传递

时间:2013-06-21 20:17:13

标签: mysql search stored-procedures reflection

是否可以通过存储过程传递准备好的SELECT语句并执行它?分别 - 是否可以在存储的MySQL过程中在SELECT语句中动态创建WHERE条件?

我们希望启用超过40列的变量搜索。这意味着,有40 * 40种组合,我们也可以硬编码(并得到一些解决方案),但在我看来它太强暴的方法。数据集大约有数千条记录。

1 个答案:

答案 0 :(得分:2)

这是完全可能的。以下是您所讨论的使用插入和更新而不是选择的示例,但这是您需要的基本形式。此过程的目的是动态插入或更新。此查询的参数是insert或update语句的变量子句。我希望这个例子有助于解释你想做的事情是可能的:

DROP procedure if exists `test`.`upsert_event`;
DELIMITER $$

CREATE PROCEDURE `test`.`upsert_event`(IN UPDATE_PARAM VARCHAR(10240), IN INSERT_PARAM VARCHAR(10240), IN REMOTE_ID_STRING VARCHAR(255))
BEGIN

    DECLARE event_id_value INT(12) DEFAULT 0;
    DECLARE id_for_update INT(12) DEFAULT 0;

    # this temp table allows results to be returned and gets around a bug in our version of mysql
    CREATE TEMPORARY TABLE IF NOT EXISTS result_set(
        event_id int(12) DEFAULT 0,
        is_inserted tinyint(1) DEFAULT 0
    ) engine = memory;

    SELECT `events`.`id` INTO id_for_update FROM `events` WHERE `events`.`remote_id` = REMOTE_ID_STRING limit 1;

    # declare the variables that will be needed
    IF id_for_update != 0 THEN

        # build the update clause that you need
        SET @query_as_string = CONCAT('UPDATE `events` SET ', UPDATE_PARAM, ' WHERE `events`.`remote_id` = ', REMOTE_ID_STRING);

        PREPARE statement_1 FROM @query_as_string;
        EXECUTE statement_1;
        DEALLOCATE PREPARE statement_1;

        INSERT INTO `result_set` (event_id, is_inserted) VALUES (id_for_update, 0);

    ELSE            
        #build the insert clause that you need
        SET @query_as_string = CONCAT('INSERT INTO `events` ', INSERT_PARAM);

        PREPARE statement_1 FROM @query_as_string;
        EXECUTE statement_1;
        DEALLOCATE PREPARE statement_1;

        # set the id of the value update/inserted and return that as a reference
        SELECT LAST_INSERT_ID() INTO event_id_value;
        INSERT INTO `result_set` (event_id, is_inserted) VALUES (event_id_value, 1);

    END IF;

    SELECT * FROM `result_set` WHERE 1 LIMIT 1;
    DROP TABLE result_set;

END $$
DELIMITER ;