我正在创建此存储过程,并且我在过程中第一次选择时出现语法错误。此过程有一个名为selProyecto的IN var。
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;
获取客户总数,然后我声明一个游标来迭代每个客户端。在游标内部,我尝试声明另一个游标来获取该客户端的总工作天数。最后,我用函数计算工作日的百分比。
问题是它在第一次选择之前抛出语法错误。
我已尝试使用相同的结果更改SET num_clientes = (SELECT COUNT(clientes.id) from clientes WHERE id_proyecto = selProyecto);
的句子
答案 0 :(得分: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
答案 1 :(得分: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
正如您所看到的嵌套CURSORS,我们必须在DECLARE部分中定义第一个,然后声明处理程序。在LOOP内部,我们必须定义一个新的BLOCK并执行下一个CURSOR LOOP。