我正在创建一个分页类,需要将两个参数传递给我的LIMIT子句的MySQL存储过程。
我将它们作为INT传递并尝试这样的事情
SELECT *
FROM
`MyTable`
LIMIT
MyFirstParamInt, MySecondParamInt
当我尝试保存sproc时,它给了我一个错误。有没有办法做到这一点,我只是错过了?或者我将不得不评估整个查询并执行它?
答案 0 :(得分:14)
在5.5.6之前,LIMIT
无法在MySQL存储过程中进行参数化。您需要动态构建查询并执行它。
在5.5.6及更高版本中,您可以将存储的procs参数作为参数传递给LIMIT
和OFFSET
,只要它们是INTEGER
。
答案 1 :(得分:10)
来自http://dev.mysql.com/doc/refman/5.1/en/select.html:
LIMIT子句可用于约束SELECT语句返回的行数。 LIMIT需要一个或两个数字参数,必须都是非负整数常量(使用预准备语句时除外)。
这是准备好的声明示例,可能对您有所帮助:
SET @skip=1;
SET @rows=5;
PREPARE STMT FROM 'SELECT * FROM table LIMIT ?, ?';
EXECUTE STMT USING @skip, @rows;
答案 2 :(得分:10)
我刚刚找到了一个可能有用的解决方案。 在存储过程中使用声明的变量并将它们设置为参数
例如
CREATE PROCEDURE MyProcedure(
IN paramFrom INT,
IN paramTo INT
)
BEGIN
DECLARE valFrom INT;
DECLARE valTo INT;
SET valFrom = paramFrom;
SET valTo = paramTo;
SELECT * FROM myTable LIMIT valFrom, valTo;
END
答案 3 :(得分:1)
以下在MySQL 5.5.35中运行良好。它也适用于另一个程序,其中SELECT
语句中使用了相同的DECLARE . . . CURSOR
。
CREATE PROCEDURE `test`(
IN `lim_val` INT,
IN `lim_offset` INT
)
BEGIN
SELECT array_ident_id
FROM ArrayIdents
ORDER BY array_ident_id
LIMIT lim_val OFFSET lim_offset;
END;
答案 4 :(得分:0)
call user_list
(v_private_key,v_user_id,v_pageIndex,v_limit,v_image_path,
@o_rec_count,
@o_error_code,
@o_error_message)
DECLARE v_QueryLimit TEXT DEFAULT "";
DECLARE v_Select TEXT DEFAULT "";
DECLARE v_where TEXT DEFAULT '';
DECLARE v_From TEXT DEFAULT "";
DECLARE v_group_by TEXT DEFAULT " ";
DECLARE v_having TEXT DEFAULT "";
DECLARE v_OrderBy TEXT DEFAULT "";
SET o_error_code = '200';
SET v_Select = CONCAT(" SELECT
AES_DECRYPT(email,'",v_private_key,"') AS email,
AES_DECRYPT(first_name,'",v_private_key,"') AS first_name,
AES_DECRYPT(last_name,'",v_private_key,"') AS last_name,
AES_DECRYPT(mobile_no,'",v_private_key,"') AS mobile_no,
CONCAT(AES_DECRYPT(first_name,'",v_private_key,"'),' ', AES_DECRYPT(last_name,'",v_private_key,"')) as full_name,
CONCAT('",v_image_path,"','profile/',IFNULL(thumb,'user_thumb.png')) AS thumb,
CONCAT('",v_image_path,"','profile/small/',IFNULL(thumb,'user_thumb.png')) AS thumb_small,
IFNULL(country_code,'+91') as country_code,
IFNULL(unique_code,'') as user_code
");
SET v_From = CONCAT(" FROM userinfo WHERE role_group = 2 AND id != ",v_user_id," ");
IF (v_PageIndex) > 0 THEN
SET v_QueryLimit = CONCAT(" LIMIT ", v_limit, "," , v_pageIndex);
END IF;
-- set v_group_by = concat(' GROUP BY ut.user_card_id, ');
SET @rec_Query= CONCAT(v_Select
,v_From
,v_Where
,v_group_by
,v_having
,v_OrderBy);
/**************** Get Record Count **************/
SET @cnt_Query = CONCAT("Select Count(*) INTO @o_rec_count FROM (",@rec_Query,") AS tmp");
PREPARE c2 FROM @cnt_Query;
EXECUTE c2;
SET o_rec_count=@o_rec_count;
/**************** Calculate Limit **************/
IF (v_limit != "" && v_pageIndex != "") AND @o_rec_count>0 THEN
CALL Calculate_Paging_Index(@o_rec_count ,v_limit,v_pageIndex,@new_start_limit);
SET v_QueryLimit = CONCAT(" LIMIT ",@new_start_limit, ",",v_limit);
END IF;
SET @vv2_Query= CONCAT(v_Select
,v_From
,v_Where
,v_group_by
,v_having
,v_OrderBy
,v_QueryLimit);
PREPARE s2 FROM @vv2_Query;
EXECUTE s2;
SET o_error_message = "success";
计算页面索引SP
CREATE PROCEDURE calculate_paging_index (in_count,in_limit,in_page,@out_start_limit)
在此处输入代码
DECLARE count1 INT;
DECLARE total_pages INT;
SET count1 = in_count;
IF( count1 > 0 ) THEN
SET total_pages = CEIL(count1/in_limit);
ELSE
SET total_pages = 0;
END IF;
IF (in_page > total_pages) THEN
SET in_page=total_pages;
END IF;
SET out_start_limit = in_limit * in_page - in_limit;
答案 5 :(得分:-1)
没有陈述的分页:
create PROCEDURE test(
IN first_rec integer,
IN rec_count integer
)
BEGIN
-- return --
SET @rownum=0;
SELECT * FROM (
SELECT
user.*, @rownum:=@rownum+1 AS rn FROM user
) t WHERE rn>=first_rec and rn<first_rec+rec_count;
END;;
答案 6 :(得分:-1)
简单的解决方案
CREATE PROCEDURE `some_proc` (
IN _START INTEGER,
IN _LIMIT INTEGER
)
BEGIN
PREPARE STMT FROM
" SELECT * FROM products LIMIT ?,? ";
SET @START = _START;
SET @LIMIT = _LIMIT;
EXECUTE STMT USING @START, @LIMIT;
DEALLOCATE PREPARE STMT;
END $$
在存储过程中尝试准备语句。