2008-10-28 9 views
32

J'écris une procédure stockée où j'ai un paramètre d'entrée appelé my_size qui est un int, je veux être capable d'utiliser une clause limit dans une instruction select. Apparemment, ce n'est pas supporté, y a-t-il un moyen de contourner ce problème?Variable LIMIT Clause dans MySQL

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

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

Si vous avez le contrôle sur la version de MySQL que vous utilisez, il semble que cela est fixé à partir de v5.5.6. http://bugs.mysql.com/bug.php?id=11918 – Hammerite

+0

trouvé une autre solution simple http://stackoverflow.com/a/4315661 – user3011839

+0

Notez que dans * MySQL 5.7.16 * (et peut-être d'autres) le ' LIMIT @nrows OFFSET @ noffset' dans une routine stockée semble également être rejeté, alors qu'un 'LIMIT nrows OFFSET noffset' est accepté, aussi longtemps que vous 'DECLARE nrows INT; DÉCLARER noffset INT' au début de la routine. – Xenos

Répondre

9

Une recherche a été effectuée this article. J'ai collé le texte pertinent ci-dessous.

Voici un post sur le forum montrant un exemple de déclarations préparées à laisser vous attribuez une valeur variable à la clause limite:

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

Cependant, je pense que ce bug devrait obtenir un peu d'attention parce que je peux Imaginez que les instructions préparées au sein d'une procédure permettent toutes les optimisations lors de la compilation de la procédure. J'ai le sentiment que instructions sont compilées et exécutées à l'exécution de la procédure, qui probaby a un impact négatif sur l'efficacité. Si la limite clause pouvait accepter les variables de procédure normales (par exemple, une procédure argument), alors la base de données pouvait encore effectuer des optimisations à la compilation sur le reste de la requête, au sein de la procédure. Ce permettrait probablement une exécution plus rapide de la procédure. Je ne suis pas expert cependant.

12

Je sais que cette réponse est arrivée tardivement, mais essayez SQL_SELECT_LIMIT.

Exemple:

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

Malheureusement, ne semble pas soutenir un argument pour la position de départ, comme 5,2 pour prendre 2 lignes de la position 5. Mais à moins que vous en ayez besoin, il peut faire l'affaire. – Gruber

+0

Malheureusement, cette astuce ne fonctionne pas pour une partie 'SELECT ... 'de requêtes telles que' REPLACE ... SELECT ... '. – Apostle

7

Cette fonction a été ajoutée à MySQL 5.5.6. Cochez cette case link.

J'ai mis à niveau vers MySQL 5.5 juste pour cette fonctionnalité et fonctionne très bien. 5.5 a également beaucoup de mises à niveau de performance en place et je le recommande totalement.

13

Stored Procedure

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 ; 

USAGES

call get_users(1, 10); 
+0

a travaillé le mieux pour moi - merci – auval

2

Une autre façon, le même que celui écrit "Pradeep Sanjaya", mais en utilisant 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; 
+0

C'est une excellente solution avec l'utilisation ** ** PREPARE ** et ** 'EXECUTE' ** déclaration. Une remarque importante: nous n'avons pas besoin d'utiliser la procédure Create. Nous pouvons également utiliser les instructions ** 'PREPARE' ** et **' EXECUTE' ** dans le code SQL majeur. –

20

Pour ceux , qui ne peut pas utiliser MySQL 5.5.6+ et ne veulent pas écrire une procédure stockée, il existe une autre variante. Nous pouvons ajouter une clause where sur une sous-sélection avec ROWNUM.

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

J'aime l'initialisation de @rownum dans le SELECT, sympa! – andig

1

de la version MySQL 5.5.6, vous pouvez spécifier LIMIT et OFFSET avec des variables/paramètres.

Pour référence, voir le 5.5 Manual, le 5.6 Manual et @ Quassnoi de answer

Questions connexes