web-dev-qa-db-fra.com

Utilisation de variable dans une clause LIMIT dans MySQL

J'écris une procédure stockée où j'ai un paramètre d'entrée appelé my_size qui est un ENTIER . Je veux pouvoir l'utiliser dans une clause LIMIT dans une instruction SELECT. Apparemment, cela n'est pas pris en charge, existe-t-il un moyen de contourner ce problème?

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

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

Une recherche s'est révélée cet article . J'ai collé le texte pertinent ci-dessous.

Voici un article de forum montrant un exemple d'instructions préparées vous permettant d'affecter une valeur variable à la clause limit:

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

Cependant, je pense que ce bogue devrait attirer l'attention, car je ne peux pas imaginer que les instructions préparées dans une procédure permettront des optimisations au moment de la compilation. J'ai le sentiment que les instructions préparées sont compilées et exécutées au moment de l'exécution de la procédure, ce qui a probablement un impact négatif sur l'efficacité. Si la clause limite pouvait accepter des variables de procédure normales (par exemple, un argument de procédure), la base de données pourrait toujours effectuer des optimisations au moment de la compilation sur le reste de la requête, dans la procédure. Cela entraînerait probablement une exécution plus rapide de la procédure. Je ne suis cependant pas un expert.

10
TheSoftwareJedi

Pour ceux qui ne peuvent pas utiliser MySQL 5.5.6+ et ne veulent pas écrire une procédure stockée, il existe une autre variante. Nous pouvons ajouter la 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;
22
ENargit

PROCÉDURE STOCKÉE

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 ;

UTILISATION

call get_users(1, 10);
14
Pradeep Sanjaya

Je sais que cette réponse est arrivée tard, 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;
12
user888112

Cette fonctionnalité a été ajoutée à MySQL 5.5.6. Vérifiez cela lien out.

J'ai mis à niveau vers MySQL 5.5 juste pour cette fonctionnalité et fonctionne très bien. 5.5 dispose également de nombreuses améliorations de performances et je le recommande vivement.

9
Jiho Kang

Une autre façon, la même que celle écrite "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;

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

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

1
rekaszeru