2008-10-28 18 views
32

Piszę procedurę przechowywaną, gdzie mam parametr wejściowy o nazwie my_size, który jest int, chcę mieć możliwość użycia w klauzuli limit w instrukcji select. Najwyraźniej nie jest to obsługiwane, czy istnieje sposób obejścia tego?Zmienna LIMIT Klauzula w 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

Jeśli masz kontrolę nad tym, którą wersję MySQL używasz, wygląda to tak jest ustalona począwszy v5.5.6. http://bugs.mysql.com/bug.php?id=11918 – Hammerite

+0

znalazłem inne proste rozwiązanie http://stackoverflow.com/a/4315661 – user3011839

+0

Zauważ, że w * MySQL 5.7.16 * (i może innych) ' LIMIT @nrows OFFSET @ noffset' w przechowywanej procedurze wydaje się być odrzucony, podczas gdy 'LIMIT zgłasza OFFSET noffset' jest akceptowany, o ile' DECLARE nrows INT; DECLARE noffset INT' na początku rutyny. – Xenos

Odpowiedz

9

Znaleziono wyszukiwanie this article. Wkleiłem odpowiedni tekst poniżej.

Oto Post Forum pokazujący przykład sporządzanych sprawozdań pozwalając przypisać wartość zmiennej klauzuli LIMIT:

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

Myślę jednak, że ten błąd powinien dostać trochę uwagi, ponieważ mogę "t Wyobraź sobie, że przygotowane instrukcje w ramach procedury pozwolą na dowolne optymalizacje w czasie kompilacji w trybie kompilacji . Mam wrażenie, że przygotowane instrukcje zostały skompilowane i wykonane w czasie wykonywania procedury, co może mieć negatywny wpływ na wydajność. Jeśli klauzula limitu akceptuje normalne zmienne proceduralne (np. Argumenty procedury ), to baza danych może nadal wykonywać kompilację podczas optymalizacji pozostałych zapytań w ramach procedury. Ten prawdopodobnie przyniesie szybsze wykonanie procedury. Nie jestem jednak ekspertem .

12

Wiem, że ta odpowiedź się spóźniła, ale spróbuj SQL_SELECT_LIMIT.

przykład:

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

Niestety nie obsługuje on argumentu dla pozycji wyjściowej, np. 5,2 dla przyjmowania 2 rzędów od pozycji 5. Ale jeśli nie jest to potrzebne, może to wystarczyć. – Gruber

+0

Niestety, ta sztuczka nie działa dla części "SELECT ..." takich jak 'REPLACE ... SELECT ...'. – Apostle

7

Funkcja ta została dodana do MySQL 5.5.6. Sprawdź to link.

Zaktualizowałem do MySQL 5.5 tylko dla tej funkcji i działa świetnie. 5.5 również ma wiele ulepszeń wydajności i całkowicie go polecam.

13

procedura przechowywana

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 ; 

ZUŻYCIA

call get_users(1, 10); 
+0

pracował najlepiej dla mnie - dzięki – auval

2

inny sposób, tak samo jak napisał "Pradeep Sanjaya", ale przy użyciu 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

Jest to świetne rozwiązanie z użyciem instrukcji ** 'PREPARE' ** i **' EXECUTE' **. Jedna ważna uwaga: nie musimy używać procedury tworzenia. Możemy użyć instrukcji ** 'PREPARE' ** i **' EXECUTE' ** również w głównym kodzie sql. –

20

Dla tych , którzy nie mogą używać MySQL 5.5.6+ i nie chcesz pisać procedura przechowywana, istnieje inny wariant. Możemy dodać klauzul where na podselekcji z ROWNUM.

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

Podoba mi się inicjalizacja @rownum wewnątrz SELECT, miło! – andig