具有光标预选数据的MySQL过程

时间:2014-11-07 20:33:20

标签: mysql stored-procedures mysql-error-1064

所以,

我在这里遇到了一个问题,那就是让我发疯,我认为这是一个愚蠢的错误,所以我不是MySQL的新手,但它不像我想的那样工作。

尝试将此语句部署到MySQL后,我得到了这个Erro:

  

错误1064(42000):您的SQL语法有错误;查看与您的MySQL服务器版本对应的手册,以便在“DEClARE estoque CURSOR FOR”附近使用正确的语法               选择                   validade,           '在第26行

这是我的SP

DROP PROCEDURE IF EXISTS SP_SEPARA_MATERIAL;
DELIMITER $$
CREATE PROCEDURE SP_SEPARA_MATERIAL(IN MovimentoItemPedidoID INT(11))
BEGIN
    DECLARE EMPRESA_ID int;
    DECLARE MOVIMENTO_ID int;
    DECLARE ARMAZEM_ID int;
    DECLARE CLIENTE_ID int;
    DECLARE FLUXO_LOGISTICO_ID int;
    DECLARE PRODUTO_ID int;
    DECLARE VOLUME_ID int;
    DECLARE VALIDADE date;
    DECLARE LOTE int;
    DECLARE NOTA int;
    DECLARE PRECO double;
    DECLARE QTD_BOM double;
    DECLARE QTD_RUIM double;
    DECLARE ESTOQUE_BOM double;
    DECLARE ESTOQUE_RUIM double;
    DECLARE RET_BOM double;
    DECLARE RET_RUIM double;
    DECLARE finished INTEGER DEFAULT 0;

    -- Catch head data of move
    SELECT movimento_id, fluxo_logistico_id, produto_id, quantidade_bom, quantidade_ruim INTO MOVIMENTO_ID, FLUXO_LOGISTICO_ID, PRODUTO_ID, QTD_BOM, QTD_RUIM FROM movimento_itens_pedido WHERE id = MovimentoItemPedidoID;
    SELECT empresa_id, cliente_id, armazem_id INTO EMPRESA_ID, CLIENTE_ID, ARMAZEM_ID FROM movimento WHERE id = MOVIMENTO_ID;

    DEClARE estoque CURSOR FOR
        SELECT
            validade,
            lote_numero,
            nota_numero,
            preco_unitario,
            volume_id,
            quantidade_bom,
            quantidade_ruim
        FROM
            estoque_enderecado_reserva_picking
        WHERE
            empresa_id = EMPRESA_ID AND
            armazem_id = ARMAZEM_ID AND
            cliente_id = CLIENTE_ID AND
            produto_id = PRODUTO_ID AND
            (quantidade_bom>=0 OR quantidade_ruim>=0);

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;

    OPEN estoque;
    loop_separacao: LOOP
        FETCH estoque INTO
            VALIDADE,
            LOTE,
            NOTA,
            PRECO,
            VOLUME_ID,
            ESTOQUE_BOM,
            ESTOQUE_RUIM;

        IF finished = 1 THEN
            LEAVE loop_separacao;
        END IF;

        IF QTD_BOM>0 AND ESTOQUE_BOM>0 THEN
            SET RET_BOM = 0;
            IF ESTOQUE_BOM>=QTD_BOM THEN
                SET RET_BOM = QTD_BOM;
            ELSE
                SET RET_BOM = ESTOQUE_BOM;
            END IF;
        END IF;

        IF QTD_RUIM>0 AND ESTOQUE_RUIM>0 THEN
            SET RET_RUIM = 0;
            IF ESTOQUE_RUIM>=QTD_RUIM THEN
                SET RET_RUIM = QTD_RUIM;
            ELSE
                SET RET_RUIM = ESTOQUE_RUIM;
            END IF;
        END IF;

        IF RET_BOM>0 OR RET_RUIM>0 THEN
            INSERT INTO movimento_picking_volume_itens (movimento_id,armazem_id,cliente_id,fluxo_logistico_id,produto_id,quantidade_bom,quantidade_ruim,validade,lote_numero,nota_numero,preco_unitario,volume_id) 
            VALUES (MOVIMENTO_ID,ARMAZEM_ID,CLIENTE_ID,FLUXO_LOGISTICO_ID,PRODUTO_ID,RET_BOM,RET_RUIM,VALIDADE,LOTE,NOTA,PRECO,VOLUME_ID);
            SET QTD_BOM = (QTD_BOM - RET_BOM);
            SET QTD_RUIM = (QTD_RUIM - RET_RUIM);
        END IF;

        IF QTD_BOM=0 AND QTD_RUIM=0 THEN
            SET finished = 1;
            LEAVE loop_separacao;
        END IF;

    END LOOP loop_separacao;
    CLOSE estoque;

END $$
DELIMITER ;

1 个答案:

答案 0 :(得分:0)

检查:13.6.6.2 Cursor DECLARE Syntax

  

...

     

游标声明必须出现在处理程序声明之前和之后   变量和条件声明。

     

...

尝试:

DROP PROCEDURE IF EXISTS SP_SEPARA_MATERIAL;

DELIMITER $$

CREATE PROCEDURE SP_SEPARA_MATERIAL(IN MovimentoItemPedidoID INT(11))
BEGIN
    DECLARE EMPRESA_ID int;
    DECLARE MOVIMENTO_ID int;
    DECLARE ARMAZEM_ID int;
    DECLARE CLIENTE_ID int;
    DECLARE FLUXO_LOGISTICO_ID int;
    DECLARE PRODUTO_ID int;
    DECLARE VOLUME_ID int;
    DECLARE VALIDADE date;
    DECLARE LOTE int;
    DECLARE NOTA int;
    DECLARE PRECO double;
    DECLARE QTD_BOM double;
    DECLARE QTD_RUIM double;
    DECLARE ESTOQUE_BOM double;
    DECLARE ESTOQUE_RUIM double;
    DECLARE RET_BOM double;
    DECLARE RET_RUIM double;
    DECLARE finished INTEGER DEFAULT 0;

    /* MOVE AFTER THE DECLARE CONTINUE HANDLER ...
    -- Catch head data of move
    SELECT movimento_id, fluxo_logistico_id, produto_id, quantidade_bom, quantidade_ruim INTO MOVIMENTO_ID, FLUXO_LOGISTICO_ID, PRODUTO_ID, QTD_BOM, QTD_RUIM FROM movimento_itens_pedido WHERE id = MovimentoItemPedidoID;
    SELECT empresa_id, cliente_id, armazem_id INTO EMPRESA_ID, CLIENTE_ID, ARMAZEM_ID FROM movimento WHERE id = MOVIMENTO_ID;
    MOVE AFTER THE DECLARE CONTINUE HANDLER ... */

    DEClARE estoque CURSOR FOR
        SELECT
            validade,
            lote_numero,
            nota_numero,
            preco_unitario,
            volume_id,
            quantidade_bom,
            quantidade_ruim
        FROM
            estoque_enderecado_reserva_picking
        WHERE
            empresa_id = EMPRESA_ID AND
            armazem_id = ARMAZEM_ID AND
            cliente_id = CLIENTE_ID AND
            produto_id = PRODUTO_ID AND
            (quantidade_bom>=0 OR quantidade_ruim>=0);

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;

    -- Catch head data of move
    SELECT movimento_id, fluxo_logistico_id, produto_id, quantidade_bom, quantidade_ruim INTO MOVIMENTO_ID, FLUXO_LOGISTICO_ID, PRODUTO_ID, QTD_BOM, QTD_RUIM FROM movimento_itens_pedido WHERE id = MovimentoItemPedidoID;
    SELECT empresa_id, cliente_id, armazem_id INTO EMPRESA_ID, CLIENTE_ID, ARMAZEM_ID FROM movimento WHERE id = MOVIMENTO_ID;

    OPEN estoque;
    loop_separacao: LOOP
        FETCH estoque INTO
            VALIDADE,
            LOTE,
            NOTA,
            PRECO,
            VOLUME_ID,
            ESTOQUE_BOM,
            ESTOQUE_RUIM;

        IF finished = 1 THEN
            LEAVE loop_separacao;
        END IF;

        IF QTD_BOM>0 AND ESTOQUE_BOM>0 THEN
            SET RET_BOM = 0;
            IF ESTOQUE_BOM>=QTD_BOM THEN
                SET RET_BOM = QTD_BOM;
            ELSE
                SET RET_BOM = ESTOQUE_BOM;
            END IF;
        END IF;

        IF QTD_RUIM>0 AND ESTOQUE_RUIM>0 THEN
            SET RET_RUIM = 0;
            IF ESTOQUE_RUIM>=QTD_RUIM THEN
                SET RET_RUIM = QTD_RUIM;
            ELSE
                SET RET_RUIM = ESTOQUE_RUIM;
            END IF;
        END IF;

        IF RET_BOM>0 OR RET_RUIM>0 THEN
            INSERT INTO movimento_picking_volume_itens (movimento_id,armazem_id,cliente_id,fluxo_logistico_id,produto_id,quantidade_bom,quantidade_ruim,validade,lote_numero,nota_numero,preco_unitario,volume_id) 
            VALUES (MOVIMENTO_ID,ARMAZEM_ID,CLIENTE_ID,FLUXO_LOGISTICO_ID,PRODUTO_ID,RET_BOM,RET_RUIM,VALIDADE,LOTE,NOTA,PRECO,VOLUME_ID);
            SET QTD_BOM = (QTD_BOM - RET_BOM);
            SET QTD_RUIM = (QTD_RUIM - RET_RUIM);
        END IF;

        IF QTD_BOM=0 AND QTD_RUIM=0 THEN
            SET finished = 1;
            LEAVE loop_separacao;
        END IF;

    END LOOP loop_separacao;
    CLOSE estoque;

END $$

DELIMITER ;