0

SO に関する別の質問に対する潜在的な解決策を熟考しているときに、プロシージャ内で準備済みステートメントを使用することを検討し始めました (関数に動的 SQL がないのは悲しいことです)。プロシージャで a を実行する単純なアプローチはPREPARE、セッション中に最初にプロシージャが呼び出されたときにのみステートメントを準備する必要があるため、非効率的です。まだ存在しない場合にのみ、MySQL でステートメントを準備することは可能ですか? 準備されたステートメントの存在を確認する方法はありますか?

これは、人々が遊ぶためのサンプル手順です。SELECT指定されたテーブルから指定されたタイプのすべての列を含むステートメントを作成します。

DROP PROCEDURE IF EXISTS select_columns_of_type_statement;
delimiter //
CREATE PROCEDURE select_columns_of_type_statement(IN db VARCHAR(255), IN tbl VARCHAR(255), IN type VARCHAR(255), OUT result VARCHAR(4095))
  READS SQL DATA
  NOT DETERMINISTIC -- as tables can be ALTERed
BEGIN
    SET @scots_db=db, @scots_tbl=tbl, @scots_type=type;
    PREPARE generate_scots FROM "SELECT CONCAT(
          'SELECT ',
          GROUP_CONCAT(COLUMN_NAME SEPARATOR ', '),
          ' FROM `', ?, '`.`', ?, '` '
          )
      FROM INFORMATION_SCHEMA.COLUMNS
      WHERE TABLE_SCHEMA=? AND TABLE_NAME=? AND data_type=?
      INTO @scots_stmt";
    EXECUTE generate_scots USING @scots_db, @scots_tbl, @scots_db, @scots_tbl, @scots_type;
    SET result = @scots_stmt;
END //
delimiter ;

使用例:

CALL select_columns_of_type_statement('mysql', 'user', 'int', @stmt);
SELECT @stmt;
-- or even:
SET @stmt=CONCAT(@stmt, 'LIMIT 3');
PREPARE user_int_cols FROM @stmt;
EXECUTE user_int_cols;

ユーザー変数を多用しなければならないことも悲しいです。

4

1 に答える 1

0

存在を確認することはできないかもしれませんが、試行錯誤のパターンは機能します。DECLARE準備済みステートメントを定義して実行し、準備済みステートメントをハンドラーの外部で実行するエラーハンドラー。ステートメントが存在しない場合は、エラー ハンドラーが実行されます。きれいではありませんが、機能します。

DROP PROCEDURE IF EXISTS select_columns_of_type_statement;
delimiter //
CREATE PROCEDURE select_columns_of_type_statement(IN db VARCHAR(255), IN tbl VARCHAR(255), IN type VARCHAR(255), OUT result VARCHAR(4095))
  READS SQL DATA
  NOT DETERMINISTIC -- as tables can be ALTERed
BEGIN
    DECLARE CONTINUE HANDLER
      FOR 1243
      BEGIN
        PREPARE generate_scots FROM "SELECT CONCAT(
              'SELECT ',
              GROUP_CONCAT(COLUMN_NAME SEPARATOR ', '),
              ' FROM `', ?, '`.`', ?, '` '
              )
          FROM INFORMATION_SCHEMA.COLUMNS
          WHERE TABLE_SCHEMA=? AND TABLE_NAME=? AND data_type=?
          INTO @scots_stmt";
        EXECUTE generate_scots USING @scots_db, @scots_tbl, @scots_db, @scots_tbl, @scots_type;
      END;
    SET @scots_db=db, @scots_tbl=tbl, @scots_type=type;
    EXECUTE generate_scots USING @scots_db, @scots_tbl, @scots_db, @scots_tbl, @scots_type;
    SET result = @scots_stmt;
END //
delimiter ;
于 2012-04-29T04:47:40.307 に答える