MySQL存储过程返回多个参数

时间:2016-05-11 13:49:44

标签: mysql database stored-procedures

我是存储过程的noobie。现在我有一个有效,但我想学习如何优化它。

CREATE DEFINER=`simonh`@`%` PROCEDURE `get_normalized_client_id`(IN source_id INT, IN source_division VARCHAR(255), IN source_currency VARCHAR(255), OUT NORMALIZED_ID INT, OUT NAME VARCHAR(255), OUT ADDRESS VARCHAR(255))
BEGIN

IF source_id > 100000 THEN SET source_id = source_id - 100000; END IF;

SELECT
CLIENT.NEW_GROUP_REFERENCE_NUMBER INTO NORMALIZED_ID
FROM ccis_vendors.client_id SOURCE
INNER JOIN ccis_vendors.receivable CLIENT ON CLIENT.id = SOURCE.ACCOUNT_ID
WHERE SOURCE.number = source_id AND SOURCE.division = source_division;

SELECT
CLIENT.name INTO NAME
FROM ccis_vendors.client_id SOURCE
INNER JOIN ccis_vendors.receivable CLIENT ON CLIENT.id = SOURCE.ACCOUNT_ID
WHERE SOURCE.number = source_id AND SOURCE.division = source_division;

SELECT
CONCAT(IFNULL(CLIENT.OPERATION_STREET,''), ' ', IFNULL(CLIENT.OPERATION_CITY,''), ' ', 
IFNULL(CLIENT.OPERATION_STATE_PROVINCE, ''), ' ', IFNULL(CLIENT.OPERATION_ZIP, '')) INTO ADDRESS
FROM ccis_vendors.client_id SOURCE
INNER JOIN ccis_vendors.receivable CLIENT ON CLIENT.id =  SOURCE.ACCOUNT_ID
WHERE SOURCE.number = source_id AND SOURCE.division = source_division;

END

如您所见,我使用相同的查询3次来填充3个OUT参数。

我的问题是,有没有办法只用一个查询来做到这一点?

感谢。

编辑: 我明白为什么INTO现在不适合我。我的语法错了。

这是工作版本:

CREATE PROCEDURE `t_get_normalized_client_id`(IN source_id INT, IN source_division VARCHAR(255), IN source_currency VARCHAR(255), OUT NORMALIZED_ID INT, OUT NAME VARCHAR(255), OUT ADDRESS VARCHAR(255))
BEGIN

IF source_id > 100000 THEN SET source_id = source_id - 100000; END IF;

SELECT
CLIENT.NEW_GROUP_REFERENCE_NUMBER, 
CLIENT.name,  
CONCAT(IFNULL(CLIENT.OPERATION_STREET,''), ' ',    IFNULL(CLIENT.OPERATION_CITY,''), ' ', 
IFNULL(CLIENT.OPERATION_STATE_PROVINCE, ''), ' ', IFNULL(CLIENT.OPERATION_ZIP, ''))

INTO 
NORMALIZED_ID,
NAME,
ADDRESS

FROM ccis_vendors.client_id SOURCE
INNER JOIN ccis_vendors.receivable CLIENT ON CLIENT.id = SOURCE.ACCOUNT_ID
WHERE SOURCE.number = source_id AND SOURCE.division = source_division;

END

谢谢大家!

3 个答案:

答案 0 :(得分:1)

您可以将选择简化为单个选项。而且,我建议对参数使用一致的命名约定 - 因此不太可能与列混淆:

DELIMITER $$
CREATE DEFINER=`simonh`@`%` PROCEDURE `get_normalized_client_id`(
    IN in_source_id INT,
    IN in_source_division VARCHAR(255),
    IN in_source_currency VARCHAR(255),
    OUT out_NORMALIZED_ID INT,
    OUT out_NAME VARCHAR(255),
    OUT out_ADDRESS VARCHAR(255)
)
BEGIN
    IF in_source_id > 100000 THEN
        SET in_source_id = in_source_id - 100000;
    END IF;

    SELECT out_NORMALIZED_ID := CLIENT.NEW_GROUP_REFERENCE_NUMBER,
           out_Name := CLIENT.NAME,
           out_Address := CONCAT_WS(' ', CLIENT.OPERATION_STREET, CLIENT.OPERATION_CITY,
                                    CLIENT.OPERATION_STATE_PROVINCE, CLIENT.OPERATION_ZIP
                                   )
    FROM ccis_vendors.client_id SOURCE INNER JOIN
         ccis_vendors.receivable CLIENT
         ON CLIENT.id = SOURCE.ACCOUNT_ID
    WHERE SOURCE.number = in_source_id AND SOURCE.division = in_source_division;

END;$$
DELIMITER ;

另外:

  • 我将IF放在多行上。 END IF就在那里更清楚了。一般来说,我把“结束”的东西立即置于“开头”之下,以确保正确关闭。
  • CONCAT_WS()似乎比CONCAT()更好。作为奖励,它还处理NULL值。
  • 我更喜欢:=的内联语法,而不是INTO。这真的只是风格问题。 INTO用于其他目的,例如文件访问,因此我认为:=更清晰。

答案 1 :(得分:1)

你不能这样做吗?

 CREATE DEFINER=`simonh`@`%` PROCEDURE `get_normalized_client_id`(IN source_id INT, IN source_division VARCHAR(255), IN source_currency VARCHAR(255), OUT NORMALIZED_ID INT, OUT NAME VARCHAR(255), OUT ADDRESS VARCHAR(255))
    BEGIN

IF source_id > 100000 THEN SET source_id = source_id - 100000; END IF;

SELECT
CLIENT.NEW_GROUP_REFERENCE_NUMBER INTO NORMALIZED_ID,
CONCAT(IFNULL(CLIENT.OPERATION_STREET,''), ' ', IFNULL(CLIENT.OPERATION_CITY,''), ' ', 
IFNULL(CLIENT.OPERATION_STATE_PROVINCE, ''), ' ', IFNULL(CLIENT.OPERATION_ZIP, '')) INTO ADDRESS,
CLIENT.name INTO NAME
FROM ccis_vendors.client_id SOURCE
INNER JOIN ccis_vendors.receivable CLIENT ON CLIENT.id = SOURCE.ACCOUNT_ID
WHERE SOURCE.number = source_id AND SOURCE.division = source_division;


END

答案 2 :(得分:0)

在您的开始和结束语句之间     选择     CLIENT.name INTO NAME,     CLIENT.NEW_GROUP_REFERENCE_NUMBER INTO NORMALIZED_ID,     CONCAT(IFNULL(CLIENT.OPERATION_STREET,''),'',IFNULL(CLIENT.OPERATION_CITY,''),'''&#39 ;,     IFNULL(CLIENT.OPERATION_STATE_PROVINCE,''),' ',IFNULL(CLIENT.OPERATION_ZIP,''))进入地址     来自ccis_vendors.client_id消息来源     INNER JOIN ccis_vendors.receivable CLIENT ON CLIENT.id = SOURCE.ACCOUNT_ID     WHERE SOURCE.number = source_id AND SOURCE.division = source_division;