Lançado Adianti Framework 7.6!
Clique aqui para saber mais
MySQL Stored Procedure Boa noite, colega! Estou criando uma stored procedure no MySQL e estou me deparando com o seguinte erro " SQL execution error # 1242. Response from database: Subquery returns more than 1 row" entendi que o banco está dizendo que a instrução irá retornar mais de uma linha mas não entendi porque e nem sei como acertar isso. Será que alguém poderia me dar uma força nisso? Abaixo código ...
LB
MySQL Stored Procedure  
Fechado
Boa noite, colega!

Estou criando uma stored procedure no MySQL e estou me deparando com o seguinte erro " SQL execution error # 1242. Response from database: Subquery returns more than 1 row" entendi que o banco está dizendo que a instrução irá retornar mais de uma linha mas não entendi porque e nem sei como acertar isso. Será que alguém poderia me dar uma força nisso?
Abaixo código SQL para criação da Stored Procedure.

DROP PROCEDURE IF EXISTS `VALIDAVENDA`;
CREATE DEFINER=`root`@`localhost` PROCEDURE `VALIDAVENDA`(IN ICODVENDA int(11), OUT CERRO VARCHAR(60))
BEGIN
SET @CCREDITO = (select vendas.cod_venda from vendas where vendas.cod_venda = ICODVENDA and vendas.status = 1);
SET @PRODUTO = (select vendas.cod_prod from vendas where vendas.cod_venda = ICODVENDA and vendas.status = 0);
SET @COD_TITULO = (select contas_receber.cod_titulo from contas_receber where contas_receber.cod_venda = ICODVENDA);
SELECT IF(@CCREDITO IS NULL,'OK','Já existe credito para a venda referente a devolução!') INTO CERRO;
IF CERRO = 'OK' THEN
UPDATE PRODUTO SET PRODUTO.FLAG_VENDA = "N" WHERE PRODUTO.COD_PROD = @PRODUTO;

UPDATE CONTAS_RECEBER SET CONTAS_RECEBER.STATUS = "Cancelado" WHERE CONTAS_RECEBER.COD_VENDA = ICODVENDA;

WHILE @COD_TITULO IS NOT NULL DO
DELETE FROM CR_CAIXA WHERE CR_CAIXA.COD_TITULO = @COD_TITULO;
END WHILE;

END IF;
END;

Pacotão Dominando o Adianti Framework 7
O material mais completo de treinamento do Framework.
Curso em vídeo aulas + Livro completo + Códigos fontes do projeto ERPHouse.
Conteúdo Atualizado! Versão 7.4


Dominando o Adianti 7 Quero me inscrever agora!

Comentários (5)


LB

Senhores, pesquisando o erro com mais calma e após uma boa noite de sono, consegui ajustar meu código.
Resolvi o problema e consegui criar a Stored Procedure para atender minha necessidade. Abaixo código corrigido para que tiver alguma dúvida, talvez possa ajudar. A DÚVIDA AGORA É COMO CHAMO ESSA STORED PROCEDURE UTILIZANDO O FRAME WORK ? CONSIGO FAZER ISSO DENTRO DE UM FORM CRIADO PELO ASSISTENTE DE FORMULÁRIO?

CÓDIGO FONTE:

DROP PROCEDURE IF EXISTS `VALIDAVENDA`;
CREATE DEFINER=`root`@`localhost` PROCEDURE `VALIDAVENDA`(IN ICODVENDA int(11), OUT CERRO VARCHAR(60))
BEGIN
SET @CCREDITO = (select vendas.cod_venda from vendas where vendas.cod_venda = ICODVENDA and vendas.status = 1 LIMIT 1);

SET @PRODUTO = (select vendas.cod_prod from vendas where vendas.cod_venda = ICODVENDA and vendas.status = 0 LIMIT 1);

SET @ICOUNT = (select count(contas_receber.cod_titulo) from contas_receber where contas_receber.cod_venda = ICODVENDA);

SELECT IF(@CCREDITO IS NULL,'OK','Já existe credito para a venda referente a devolução!') INTO CERRO;

IF CERRO = 'OK' THEN
UPDATE PRODUTO SET PRODUTO.FLAG_VENDA = "N" WHERE PRODUTO.COD_PROD = @PRODUTO;

UPDATE CONTAS_RECEBER SET CONTAS_RECEBER.STATUS = "Cancelado" WHERE CONTAS_RECEBER.COD_VENDA = ICODVENDA;

WHILE @ICOUNT > 0 DO
SET @COD_TITULO = (select contas_receber.cod_titulo from contas_receber where contas_receber.cod_venda = ICODVENDA limit 1);
DELETE FROM CR_CAIXA WHERE CR_CAIXA.COD_TITULO = @COD_TITULO;
SET @ICOUNT = @ICOUNT - 1;
END WHILE;
END IF;
END;
PD

Leandro,

Embora você possa a qualquer momento acionar uma instrução SQL do BD:
www.adianti.com.br/doc-framework-Persistence-Setup-SetupTransaction

... criar regras de negócio em SP's vai totalmente contra nossa ideia de criar aplicações orientadas a objetos mais legíveis. Nos últimos 20 anos, participei de mais de 40 projetos, e nunca precisamos criar uma SP. Sugiro você não apenas usar uma linguagem Orientada a Objetos, mas também programar de maneira orientada a objetos, ou seja:

Crie um método validaVenda() na classe Venda (Model);

Avalie a possibilidade de transformar cada subselect em um método, como:
Venda->temProdutos() // retorna boleano se tem ou não produtos;
ContaReceber->Cancela() // para rodar o UPDATE que cancela a venda.

Assim, você terá métodos como o ContaReceber->Cancela(), que poderá inclusive reaproveitar em outros pontos (classes de controle) do sistema.

Pense bem sobre isso, a hora de mudar é agora ;-)

Atenciosamente,
Pablo
LB

Pablo, obrigado pela resposta!

Ainda sou novo em POO mas vou me acostumar com ela logo, ainda sou da antiga que adora um bom código SQL, mas vou seguir sua dica e começar a desenvolver tudo com Orientação a objeto.

Obrigado pela ajuda, tem previsão do livro? Já estou na fila de espera estou ansioso por adquiri-lo.
PD

Oi Leandro,

Estou fazendo ajustes para a próxima edição. Acredito que em Dezembro deve estar ok.

Abraço,
Pablo
WG

Deixa eu cair de paraquedas nesse assunto!

Um ponto interessante a ser observado também é que se trabalhar com SP, vai criar dependência de um banco de dados específico e no futuro precisar mudar, terá que reescrever alguma coisa (se não todas as SPs).

Já no modelo OO, as regras estarão nas suas classes; não em um banco de dados específico. Tornando dessa forma mais fácil a migração para outros bancos, com menos esforço e até mesmo quase que completamente sem ter que reescrever código.