53

我正在编写一个存储过程,其中有一个名为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;
4

8 回答 8

31

对于那些不能使用 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;
于 2013-06-12T06:58:08.880 回答
16

存储过程

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 ;

用法

call get_users(1, 10);
于 2012-04-05T08:54:37.027 回答
15

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

这是一个论坛帖子,显示了一个准备好的语句示例,可让您将变量值分配给限制子句:

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

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

于 2008-10-28T23:04:53.803 回答
15

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

例子:

Declare rowCount int;
Set rowCount = 100;
Set SQL_SELECT_LIMIT = rowCount;
Select blah blah
Set SQL_SELECT_LIMIT = Default;
于 2011-08-13T16:38:48.807 回答
11

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

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

于 2012-01-22T15:46:43.493 回答
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;
于 2013-02-13T15:08:50.533 回答
1

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

如需参考,请参阅5.5 Manual5.6 Manual和 @Quassnoi 的回答

于 2015-06-03T06:07:53.490 回答
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 查询获得的总行数。

于 2020-02-06T20:21:43.503 回答