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 回答