在 MySQL 的 LIMIT 子句中使用变量

问题描述 投票:0回答:10

我正在编写一个存储过程,其中有一个名为 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;
mysql limit clause variables
10个回答
33
投票

对于那些无法使用 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;

17
投票

存储过程

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 ;

使用

在以下示例中,每次通过提供起始值为 1 和 11 来检索 10 条记录。1 和 11 可以是从分页作为 GET/POST 参数接收的页码。

call get_users(1, 10);
call get_users(11, 10);

15
投票

搜索出现了这篇文章。我已将相关文字粘贴在下面。

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

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

但是,我认为这个错误应该引起一些注意,因为我不能 想象一下程序中准备好的语句将允许任何 过程编译时优化。我有一种感觉,准备好了 语句在过程运行时编译和执行, 这可能会对效率产生负面影响。如果极限 子句可以接受正常的过程变量(例如,一个过程 参数),那么数据库仍然可以执行编译时 在过程中对查询的其余部分进行优化。这 可能会加快程序的执行速度。我不是专家 不过。


15
投票

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

示例:

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

12
投票

MySQL 5.5.6 中已添加此功能。 检查此链接

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


3
投票

另一种方式,与“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;

1
投票

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

LIMIT
OFFSET

有关参考,请参阅5.5手册5.6手册和@Quassnoi的answer


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查询获得的总行数。


0
投票

您必须声明一个变量,然后设置它。那么 LIMit 将会工作并将其放入 StoredProcedure 中,不确定它是否在正常查询中工作

像这样:

DECLARE rowsNr INT DEFAULT 0;  
SET rowsNr = 15;  
SELECT * FROM Table WHERE ... LIMIT rowsNr;

0
投票

看来这里很多人都想用LIMIT作为参数,而不用存储过程。

可以通过 PREPARE 和 EXECUTE 来完成,如下所示:

set @my_size = 100;
set @sql = concat("SELECT * FROM some_table LIMIT ", @my_size);
PREPARE stmt FROM @sql;
EXECUTE stmt;
© www.soinside.com 2019 - 2024. All rights reserved.