2013-10-03 145 views
7

我試圖用參數創建一個簡單的過程。MySQL(存儲)過程 - 參數和查詢

CALL new_procedure('mode', 'ASC'); 

第一個輸入是所述列中的第二是排序方向

DELIMITER $$ 

CREATE DEFINER=`root`@`localhost` PROCEDURE `new_procedure`(IN in_order_by_column varchar(20), in_order_by_direction char(4)) 
BEGIN 

    DECLARE order_by varchar(30); 
    SET @order_by = CONCAT('`', in_order_by_column, '` ', in_order_by_direction); 
/* 
    SELECT * FROM `common_tags` ORDER BY @order_by LIMIT 5; 
*/ 
    SELECT @order_by as 'c'; 

END 

在上述例子中我有它僅輸出所述2個參數,所以我可以看到發生了什麼。

結果:

"c" 
`mode` ASC 

當我運行該程序與它的預期代碼,下面。

DELIMITER $$ 

CREATE DEFINER=`root`@`localhost` PROCEDURE `new_procedure`(IN in_order_by_column varchar(20), in_order_by_direction char(4)) 
BEGIN 

    DECLARE order_by varchar(30); 
    SET @order_by = CONCAT('`', in_order_by_column, '` ', in_order_by_direction); 
    SELECT * FROM `common_tags` ORDER BY @order_by LIMIT 5; 

END 

結果

tags_id  data    mode  parent_id  position 
1   Wood    2   13    6 
2   Trippy    0   0    0 
4   Artists    1   0    1 
6   "Newest Additions" 1   0    11 
12   "Natural Elements" 2   5    8 

正如你所看到的結果不受mode排序。

任何幫助表示讚賞。

回答

10

不幸的是,你需要PREPARE整個查詢在這種情況下:

DELIMITER $$ 

DROP PROCEDURE IF EXISTS `new_procedure`$$ 

CREATE PROCEDURE `new_procedure`(IN in_order_by_column varchar(20), in_order_by_direction char(4)) 
BEGIN 
    SET @buffer = CONCAT_WS('', 
     'SELECT * FROM `common_tags` ORDER BY `', in_order_by_column, '` ', in_order_by_direction, ' LIMIT 5' 
    ); 

    PREPARE stmt FROM @buffer; 
    EXECUTE stmt; 

    DEALLOCATE PREPARE stmt; 
END$$ 

DELIMITER ; 

注:描述的方法應採用非常小心,因爲它是vulnurable SQL注入攻擊,如果使用不當。