2016-04-26 65 views
0

我正在創建此存儲過程,並且在過程中第一次選擇時出現語法錯誤。這個過程有一個名爲selProyecto的IN var。帶光標的MySQL存儲過程 - 語法錯誤

BEGIN 
    DECLARE num_clientes INT DEFAULT 0; 
    DECLARE exit_loop BOOLEAN;  
    DECLARE nInicio DATE; 
    DECLARE nFin DATE; 
    DECLARE nIdCliente INT; 
    DECLARE clientCounter INT; 
    DECLARE auxDias INT; 
    DECLARE finClientes BOOLEAN; 
    DECLARE finContratos BOOLEAN; 

    SELECT COUNT(clientes.id) from clientes WHERE id_proyecto = selProyecto INTO num_clientes; 

    DECLARE clientes_proyecto CURSOR FOR SELECT id FROM clientes WHERE id_proyecto = selProyecto; 

    -- Declaración de un manejador de error tipo NOT FOUND 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET finClientes = TRUE; 
    OPEN clientes_proyecto; 
    loop_clientesProyecto: LOOP 

    -- Recogemos la id del Cliente 
    FETCH clientes_proyecto INTO nIdCliente; 
    -- Reseteamos los días trabajados 
    SET auxDias = 0; 

    -- Abrimos un segundo cursor para iterar los contratos de ese cliente 
    DECLARE cliContratos CURSOR FOR SELECT fecha_inicio, fecha_fin FROM contratos_cliente WHERE id_cliente = nIdCliente; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET finContratos = TRUE; 
    OPEN cliContratos; 
    loop_contratos: LOOP 
     FETCH cliContratos INTO nInicio, nFin; 
     IF nFin < CURDATE() THEN 
      auxDias = auxDias + Datediff(nInicio, nFin); 
     ELSE 
      auxDias = auxDias + Datediff(nInicio, CURDATE()); 
     END IF; 
     IF finContratos THEN 
      LEAVE loop_contratos; 
     END IF; 
    end loop_contratos; 

    -- Ya tenemos los días trabajados del cliente, realizamos el cálculo del porcentaje 
    SET @porcentaje = @porcentaje + ((((auxDias)/90)*(100/num_clientes))/100) 

    IF finClientes THEN 
     LEAVE loop_clientesProyecto; 
    END IF; 

    end loop_clientesProyecto; 

END 

目的是計算90天工作的客戶的百分比,但無法保存。

首先,我將SELECT COUNT(clientes.id) from clientes WHERE id_proyecto = selProyecto INTO num_clientes;的客戶總數與之後聲明一個遊標來迭代每個客戶端。在遊標內部,我嘗試聲明另一個遊標來爲該客戶端完成總工作日。最後,我用一個函數計算工作日的百分比。

問題是它在第一次選擇之前會引發語法錯誤。

我已經tryied更改了一句:SET num_clientes = (SELECT COUNT(clientes.id) from clientes WHERE id_proyecto = selProyecto);具有相同的結果

+0

什麼是語法錯誤? – cjwfuller

+0

我在做phpMyAdmin,它說'你有一個語法錯誤附近'DECLARE clientes_proyecto CURSOR FOR SELECT ID FROM clientes WHERE id_proyecto = selProyecto;'' –

回答

1

的問題可能會在這裏:

DECLARE clientes_proyecto CURSOR FOR SELECT id FROM clientes WHERE id_proyecto = selProyecto

您正在引用selProyecto定義之前。

更新:這是我的服務器上的一個類似的例子:

mysql> DECLARE foo CURSOR FOR SELECT id FROM mysql.user WHERE id = bar; 
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECLARE foo CURSOR FOR SELECT id FROM mysql.user WHERE id = bar' at line 1 
+0

selProyecto是程序中的IN var。對不起,不發表評論。 –

0

我處理我自己。下面是代碼:

BEGIN 
    DECLARE num_clientes INT DEFAULT 0;  
    DECLARE nInicio DATE; 
    DECLARE nFin DATE; 
    DECLARE nIdCliente INT; 
    DECLARE clientCounter INT; 
    DECLARE auxDias INT; 
    DECLARE finClientes BOOLEAN; 
    DECLARE finContratos BOOLEAN; 
    DECLARE porcentaje DOUBLE; 
    DECLARE clientes_proyecto CURSOR FOR SELECT id FROM clientes WHERE id_proyecto = selProyecto; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET finClientes = TRUE; 

    SET num_clientes = (SELECT COUNT(clientes.id) from clientes WHERE id_proyecto = selProyecto); 



    -- Declaración de un manejador de error tipo NOT FOUND 

    OPEN clientes_proyecto; 
    loop_clientesProyecto: LOOP 

    -- Recogemos la id del Cliente 
    FETCH clientes_proyecto INTO nIdCliente; 
    -- Reseteamos los días trabajados 
    SET auxDias = 0; 

    BLOCK2: BEGIN 
    DECLARE cliContratos CURSOR FOR SELECT fecha_inicio, fecha_fin FROM contratos_clientes WHERE id_cliente = nIdCliente; 
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET finContratos = TRUE; 
    -- Abrimos un segundo cursor para iterar los contratos de ese cliente 
    OPEN cliContratos; 
    loop_contratos: LOOP 
     FETCH cliContratos INTO nInicio, nFin; 
     IF nFin < CURDATE() THEN 
      SET auxDias = auxDias + Datediff(nInicio, nFin); 
     ELSE 
      SET auxDias = auxDias + Datediff(nInicio, CURDATE()); 
     END IF; 
     IF finContratos THEN 
      LEAVE loop_contratos; 
     END IF; 
    END LOOP loop_contratos; 
    CLOSE cliContratos; 
    END BLOCK2; 

    -- Ya tenemos los días trabajados del cliente, realizamos el cálculo del porcentaje 
    SET porcentaje = porcentaje + ((((auxDias)/90)*(100/num_clientes))/100); 

    IF finClientes THEN 
     LEAVE loop_clientesProyecto; 
    END IF; 

    END LOOP loop_clientesProyecto; 
    CLOSE clientes_proyecto; 

    SELECT porcentaje; 

END 

正如你所看到的,我們必須定義在DECLARE節第一嵌套光標,然後聲明的處理程序。在LOOP內部,我們必須定義一個新的BLOCK並執行下一個CURSOR LOOP。