2008-10-28 35 views
32

Tôi đang viết một thủ tục lưu trữ trong đó tôi có một tham số đầu vào được gọi là my_size là một int, tôi muốn có thể sử dụng trong một mệnh đề giới hạn trong một câu lệnh chọn. Rõ ràng điều này không được hỗ trợ, có cách nào để giải quyết vấn đề này không?Điều khoản giới hạn biến trong 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

Nếu bạn có kiểm soát phiên bản của MySQL bạn sử dụng, nó trông như thế này là cố định bắt đầu từ năm v5.5.6. http://bugs.mysql.com/bug.php?id=11918 – Hammerite

+0

tìm thấy một giải pháp đơn giản khác http://stackoverflow.com/a/4315661 – user3011839

+0

Lưu ý rằng trong * MySQL 5.7.16 * (và có thể những người khác) thì ' LIMIT @nrows OFFSET @ noffset' trong một thường trình được lưu trữ dường như bị từ chối quá, trong khi một 'LIMIT nrows OFFSET noffset' được chấp nhận, miễn là bạn' DECLARE nrows INT; DECLARE noffset INT' lúc bắt đầu thường lệ. – Xenos

Trả lời

9

Tìm kiếm được bật this article. Tôi đã dán văn bản có liên quan bên dưới.

Dưới đây là một bài diễn đàn cho thấy một ví dụ về báo cáo chuẩn bị để cho bạn gán một giá trị biến mệnh đề giới hạn:

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

Tuy nhiên, tôi nghĩ rằng lỗi này sẽ nhận được một số sự chú ý bởi vì tôi có thể 't hãy tưởng tượng rằng các câu lệnh được chuẩn bị trong một quy trình sẽ cho phép bất kỳ tối ưu hóa thời gian biên dịch thủ tục nào. Tôi có cảm giác rằng các câu lệnh được chuẩn bị được biên dịch và thực hiện tại thời điểm thực hiện thủ tục, mà probaby có tác động tiêu cực đến hiệu quả. Nếu mệnh đề giới hạn có thể chấp nhận các biến thủ tục bình thường (ví dụ, một thủ tục đối số), thì cơ sở dữ liệu vẫn có thể thực hiện biên dịch tối ưu hóa trên phần còn lại của truy vấn, trong thủ tục. Điều này có khả năng sẽ thực hiện nhanh hơn thực hiện các thủ tục. Tôi không có chuyên gia .

12

Tôi biết câu trả lời này đã đến muộn, nhưng hãy thử SQL_SELECT_LIMIT.

Ví dụ:

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

Thật không may dường như không hỗ trợ một đối số cho vị trí bắt đầu, như 5,2 cho việc 2 hàng từ vị trí 5. Nhưng trừ khi bạn cần rằng nó có thể làm các trick. – Gruber

+0

Thật không may, mẹo này không hoạt động đối với một phần 'SELECT ...' của các truy vấn như 'REPLACE ... SELECT ...'. – Apostle

7

Tính năng này đã được thêm vào MySQL 5.5.6. Kiểm tra điều này link.

Tôi đã nâng cấp lên MySQL 5.5 chỉ dành cho tính năng này và hoạt động tốt. 5.5 cũng có rất nhiều nâng cấp hiệu suất tại chỗ và tôi hoàn toàn khuyên bạn nên sử dụng nó.

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 ; 

SỬ DỤNG

call get_users(1, 10); 
+0

phù hợp nhất với tôi - cảm ơn – auval

2

Một cách khác, giống như viết "Pradeep Sanjaya", nhưng sử dụng 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

Đây là giải pháp tuyệt vời khi sử dụng câu lệnh ** 'PREPARE' ** và **' EXECUTE' **. Một lưu ý quan trọng: chúng tôi không cần phải sử dụng thủ tục Tạo. Chúng ta có thể sử dụng câu lệnh ** 'PREPARE' ** và **' EXECUTE' ** trong mã sql chính. –

20

Đối với những , người không thể sử dụng MySQL 5.5.6+ và không muốn viết một thủ tục lưu sẵn, có một biến thể khác. Chúng ta có thể thêm mệnh đề where vào một subselect với ROWNUM.

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

Tôi thích khởi tạo @rownum bên trong SELECT, tốt đẹp! – andig

1

Tính đến MySQL phiên bản 5.5.6, bạn có thể chỉ định LIMITOFFSET với biến/thông số.

Để tham khảo, các 5.5 Manual, các 5.6 Manual và @ thấy Quassnoi của answer