2

準備された SELECT ステートメントをストアド プロシージャ経由で渡して実行することはできますか? それぞれ-保存されたMySQLプロシージャのSELECTステートメント内でWHERE条件を動的に作成することは可能ですか?

40 列以上の変数検索を有効にしたいと考えています。つまり、40*40 通りの組み合わせがあり、ハードコードすることもできます (そして何らかの解決策を得ることができます) が、私には強引すぎるアプローチのように思えます。データセットは約数千のレコードです。

4

1 に答える 1

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 ;
于 2013-06-21T21:53:41.517 に答える