在MySQL中的LIMIT子句中使用变量

时间:2008-10-28 22:55:07

标签: mysql variables limit clause

我正在编写一个存储过程,其中有一个名为 my_size 的输入参数,它是一个 INTEGER 。我希望能够在LIMIT语句的SELECT子句中使用它。显然这是不支持的,有没有办法解决这个问题?

# I want something like:
SELECT * FROM some_table LIMIT my_size;

# Instead of hardcoding a permanent limit:
SELECT * FROM some_table LIMIT 100;

8 个答案:

答案 0 :(得分:22)

对于那些不能使用MySQL 5.5.6+并且不想编写存储过程的人,还有另一种变体。我们可以使用ROWNUM在子选择中添加where子句。

SET @limit = 10;
SELECT * FROM (
  SELECT instances.*, 
         @rownum := @rownum + 1 AS rank
    FROM instances, 
         (SELECT @rownum := 0) r
) d WHERE rank < @limit;

答案 1 :(得分:14)

已存储的程序

DELIMITER $
create PROCEDURE get_users(page_from INT, page_size INT)
begin
SET @_page_from = page_from;
SET @_page_size = page_size;
PREPARE stmt FROM "select u.user_id, u.firstname, u.lastname from users u limit ?, ?;";
EXECUTE stmt USING @_page_from, @_page_size;
DEALLOCATE PREPARE stmt;
end$
DELIMITER ;

<强> USAGE

call get_users(1, 10);

答案 2 :(得分:12)

我知道这个答案来得晚,但请尝试SQL_SELECT_LIMIT。

示例:

Declare rowCount int;
Set rowCount = 100;
Set SQL_SELECT_LIMIT = rowCount;
Select blah blah
Set SQL_SELECT_LIMIT = Default;

答案 3 :(得分:10)

搜索结果显示this article。我已粘贴下面的相关文字。

  

这是一个论坛帖子,展示了准备好的陈述的一个例子   您为limit子句分配变量值:

     

http://forums.mysql.com/read.php?98,126379,133966#msg-133966

     

然而,我认为这个bug应该得到一些关注,因为我不能   想象一下,程序中准备好的语句将允许任何   过程编译时优化。我有一种准备的感觉   语句在过程的运行时编译和执行,   probaby对效率有负面影响。如果限制   子句可以接受正常的过程变量(比如一个过程   参数),那么数据库仍然可以执行编译时   在过程中对查询的其余部分进行优化。这个   可能会更快地执行该过程。我不是专家   虽然。

答案 4 :(得分:9)

此功能已添加到MySQL 5.5.6中。 请查看此link

我已经升级到MySQL 5.5只是为了这个功能而且效果很好。 5.5还有很多性能升级,我完全推荐它。

答案 5 :(得分:2)

另一种方式,与编写“Pradeep Sanjaya”相同,但使用CONCAT:

CREATE PROCEDURE `some_func`(startIndex INT, countNum INT)
READS SQL DATA
  COMMENT 'example'
BEGIN
  SET @asd = CONCAT('SELECT `id` FROM `table` LIMIT ',startIndex,',',countNum);
  PREPARE zxc FROM @asd;
  EXECUTE zxc;
END;

答案 6 :(得分:1)

从MySQL 5.5.6开始,您可以使用变量/参数指定 LIMIT OFFSET

供参考,请参阅5.5 Manual5.6 Manual和@ Quassnoi的answer

答案 7 :(得分:0)

我在使用MySql 5.0时遇到了同样的问题,并在@ENargit的答案的帮助下编写了一个过程:

CREATE PROCEDURE SOME_PROCEDURE_NAME(IN _length INT, IN _start INT)
BEGIN
    SET _start = (SELECT COALESCE(_start, 0));
    SET _length = (SELECT COALESCE(_length, 999999)); -- USING ~0 GIVES OUT OF RANGE ERROR
    SET @row_num_personalized_variable = 0;

    SELECT
    *,
    @row_num_personalized_variable AS records_total         
    FROM(
        SELECT
        *,
        (@row_num_personalized_variable := @row_num_personalized_variable + 1) AS row_num
        FROM some_table
    ) tb
    WHERE row_num > _start AND row_num <= (_start + _length);
END;

还将查询获得的总行包含在records_total中。