2016-05-11 3 views
1

Я хранил процедуры для хранимых процедур. Теперь у меня есть тот, который работает, но я хотел бы узнать, как его оптимизировать.Хранимая процедура MySQL возвращает несколько параметров

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.

Мой вопрос: есть ли способ сделать это только с одним запросом?

Спасибо.

EDIT: Я понимаю, почему 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 

Спасибо всем!

ответ

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 используется для других целей, таких как доступ к файлам, поэтому я думаю, что := понятнее.
+0

Возможно, mysql у меня устарели, у меня появилось сообщение об ошибке: # 1064 - У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с:: = CLIENT.NEW_GROUP_REFERENCE_NUMBER, out_Name: = CLIENT.NAME, 'в строке 12 –

+0

Версия клиента MySQL: 5.5.29 –

+0

@SimonHU. , , Работает ли версия INTO? –

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 
+0

Я попытался это сделать, но у меня появилось сообщение об ошибке, в котором CLIENT не существует, что было объявлено в INNER JOIN. –

+0

странный, вы уверены, что ваш запрос действительно? попробуйте выполнить запрос, который вы написали здесь в своем вопросе, и посмотреть, что вы получаете. –

+0

У меня эта хранимая процедура работает, и я просто хочу сделать оптимизацию. –

0

между началом работы и конечные заявления ВЫБРАТЬ CLIENT.name в имя, 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, '')) в адресную ОТ ccis_vendors.client_id ИСТОЧНИК внутреннее соединение ccis_vendors.receivable CLIENT на клиенте. id = SOURCE.ACCOUNT_ID WHERE SOURCE.number = source_id И SOURCE.division = source_division;

Смежные вопросы