Параметр процедуры SQL - PullRequest
       45

Параметр процедуры SQL

0 голосов
/ 24 апреля 2018

Я пытаюсь сделать процедуру в SQL, но у меня есть некоторые проблемы с параметрами даты

DELIMITER #
CREATE PROCEDURE conso(IN p_upcNameId VARCHAR(20), IN p_dateFrom DATE, IN p_dateTo DATE)     
BEGIN
    DECLARE done int default false;

    DECLARE v_cumule FLOAT;

    DECLARE v_reserve VARCHAR(40);
    DECLARE v_kg VARCHAR(40);
    DECLARE v_date DATETIME;

    DECLARE v_reserve_1 VARCHAR(40);
    DECLARE v_kg_1 VARCHAR(40);
    DECLARE v_date_1 DATETIME;

    DECLARE cur1 CURSOR FOR
        SELECT reserve, kg, date
        FROM
        (
            ( SELECT event_param_3 as reserve, event_param_4 as kg, event_datetime as date FROM events WHERE upcNameId = p_upcNameId AND event_code = 50 ORDER BY event_datetime DESC )
            UNION
            ( SELECT event_param_2 as reserve, event_param_3 as kg, event_datetime as date FROM events WHERE upcNameId = p_upcNameId AND event_code = 54 ORDER BY event_datetime DESC )

            UNION
            ( SELECT event_param_2 as reserve, event_param_3 as kg, event_datetime as date FROM events WHERE upcNameId = p_upcNameId AND event_code = 52 ORDER BY event_datetime DESC )
            UNION
            ( SELECT event_param_1 as reserve, event_param_2 as kg, event_datetime as date FROM events WHERE upcNameId = p_upcNameId AND event_code = 56 ORDER BY event_datetime DESC )

            UNION
            ( SELECT event_param_2 as reserve, event_param_3 as kg, event_datetime as date FROM events WHERE upcNameId = p_upcNameId AND event_code = 53 ORDER BY event_datetime DESC )
            UNION
            ( SELECT event_param_1 as reserve, event_param_2 as kg, event_datetime as date FROM events WHERE upcNameId = p_upcNameId AND event_code = 57 ORDER BY event_datetime DESC )
        ) as diffusion_programs
        ORDER BY date DESC;
    DECLARE cur2 CURSOR FOR
        SELECT reserve, kg, date
        FROM
        (
            ( SELECT event_param_3 as reserve, event_param_4 as kg, event_datetime as date FROM events WHERE upcNameId = p_upcNameId AND event_code = 50 ORDER BY event_datetime DESC )
            UNION
            ( SELECT event_param_2 as reserve, event_param_3 as kg, event_datetime as date FROM events WHERE upcNameId = p_upcNameId AND event_code = 54 ORDER BY event_datetime DESC )

            UNION
            ( SELECT event_param_2 as reserve, event_param_3 as kg, event_datetime as date FROM events WHERE upcNameId = p_upcNameId AND event_code = 52 ORDER BY event_datetime DESC )
            UNION
            ( SELECT event_param_1 as reserve, event_param_2 as kg, event_datetime as date FROM events WHERE upcNameId = p_upcNameId AND event_code = 56 ORDER BY event_datetime DESC )

            UNION
            ( SELECT event_param_2 as reserve, event_param_3 as kg, event_datetime as date FROM events WHERE upcNameId = p_upcNameId AND event_code = 53 ORDER BY event_datetime DESC )
            UNION
            ( SELECT event_param_1 as reserve, event_param_2 as kg, event_datetime as date FROM events WHERE upcNameId = p_upcNameId AND event_code = 57 ORDER BY event_datetime DESC )
        ) as diffusion_programs
        WHERE date >= p_dateFrom;
        AND date <= p_dateTo;
        ORDER BY date DESC;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    OPEN cur1;
    OPEN cur2;

    /* Create temporary table */
    CREATE TEMPORARY TABLE tmp
    (
        date DATE,
        kg FLOAT
    );
    SET v_cumule = 0;
    FETCH cur2 INTO v_reserve_1, v_kg_1, v_date_1;

    forLoop: LOOP
        /* Actual row */
        FETCH cur1 INTO v_reserve, v_kg, v_date;

        /* Next row */
        FETCH cur2 INTO v_reserve_1, v_kg_1, v_date_1;

        /* Reserves differents TODO */
        /*IF v_reserve != v_reserve_1
        END IF;*/

        IF DATE(v_date) = DATE(v_date_1) THEN SET v_cumule = v_cumule + (v_kg_1 - v_kg);
        ELSE
            INSERT INTO tmp VALUES (DATE(v_date), v_cumule);
            SET v_cumule = 0;
        END IF;

        IF done THEN LEAVE forLoop;
        END IF;
    END LOOP;

    CLOSE cur1;
    CLOSE cur2;
END#

Вы видите, что p_datefrom и p_dateto - это некоторые параметры, которые я хочу передать, когда я вызываю функцию с помощью:

DELIMITER ;
CALL conso('Name','2017-01-01','2018-01-01');
SELECT * FROM tmp;

Как видите, это интервал дат. Но я получаю эту ошибку:

1064 - Ошибка синтаксиса prés de 'AND date <= p_dateTo; ЗАКАЗАТЬ по дате DESC; ОБЪЯВИТЬ ПРОДОЛЖИТЬ HANDLER 'à la ligne 53 </p>

Можете ли вы помочь мне, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 24 апреля 2018

Есть некоторые ложные точки с запятой (терминаторы операторов).

  WHERE date >= p_dateFrom;
       AND date <= p_dateTo;
       ORDER BY date DESC;

Удалите эти

  WHERE date >= p_dateFrom
       AND date <= p_dateTo
       ORDER BY date DESC
  ;

оригинальный (неправильный) ответ :

CONTINUE HANDLER должен следовать за объявлениями переменных, но должен быть перед объявлениями курсора.(Я думаю, что это смутно задокументировано в Справочном руководстве MySQL. Хранимые программы MySQL очень точны в отношении порядка операторов.)

Чтобы исправить эту ошибку, просто переместите оператор DECLARE CONTINUE HANDLER вправо перед первым DECLARE CURSOR.

0 голосов
/ 24 апреля 2018

«дата» - зарезервированное слово в MySQL.Используйте другой псевдоним.

Кроме того, вы должны рассмотреть возможность использования оператора CASE, чтобы избавиться от нескольких операторов UNION (вы можете сделать все UNION в одном запросе).

РЕДАКТИРОВАТЬ: ошибка возникает из-за того, чтоу вас были лишние точки с запятой, как уже указывал spencer7593.

Столбцы event_param_X объявлены как varchar, но вы выполняете арифметические операции (+ -) с ними.

...