2008-10-28 41 views
32

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

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

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

如果你有超过你使用的MySQL版本控制,它看起来像这样在v5.5.6开始固定。 http://bugs.mysql.com/bug.php?id=11918 – Hammerite 2011-08-13 16:57:37

+0

发现另一个简单的解决方案http://stackoverflow.com/a/4315661 – user3011839 2013-11-20 06:20:43

+0

请注意,在* MySQL 5.7.16 *(也许其他人)的` LIMIT @nrows OFFSET @ noffset`在存储例程中似乎也被拒绝了,而'LIMIT nrows OFFSET noffset`被接受,只要你'DECLARE nrow INT';在程序开始时声明noffset INT`。 – Xenos 2017-05-18 08:04:20

回答

9

搜索出现this article。我已经粘贴了下面的相关文字。

这里的展示准备的语句让 你一个变量的值赋给限制条款的一个例子的论坛帖子:

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

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

12

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

实施例:

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

不幸的是,似乎不支持起始位置的参数,例如5,2从位置5开始取2行。但除非您需要,否则它可能会执行此操作。 – Gruber 2013-01-09 12:51:25

+0

另外不幸的是,这个技巧不适用于查询的SELECT ...部分,比如`REPLACE ... SELECT ...`。 – Apostle 2015-06-03 09:38:34

7

该功能已被添加到MySQL 5.5.6。 检查此link了。

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

13

存储过程

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); 
2

的另一种方式,同为写 “普拉迪普嘉亚”,但使用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; 
20

对于那些,谁不能使用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;