【问题标题】:MySQL Procedure with Pre-Select Data for Cursor为光标预选数据的 MySQL 过程
【发布时间】:2014-11-07 20:33:20
【问题描述】:

所以,

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

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

ERROR 1064 (42000):您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取在 'DEClARE estoque CURSOR FOR 附近使用的正确语法 选择 验证, ' 在第 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 ;

【问题讨论】:

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


    【解决方案1】:

    检查: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 ;
    

    【讨论】:

      猜你喜欢
      • 2013-03-28
      • 2021-11-23
      • 2016-08-20
      • 1970-01-01
      • 1970-01-01
      • 2016-01-27
      • 2021-08-20
      • 1970-01-01
      • 2014-05-17
      相关资源
      最近更新 更多