Aprenda MySQL

  • Página Inicial
  • Contato!
  • Tudo sobre MySQL Parte 1!
  • Tudo sobre MySQL Parte 2!
  • Tudo sobre MySQL Parte 3!
  • Tudo sobre MySQL Parte 4!
  • Tudo sobre MySQL Parte 5!
  • Tudo sobre MySQL Parte 6!
  • Tudo sobre MySQL Parte 7!
  • Tudo sobre MySQL Parte 5

    Funções Aritméticas e Operadores Aritméticos

    É possível realizar operações matemáticas simples nos valores de uma coluna e retornar resultados em uma coluna calculada. Para isso usamos os operadores comuns matemáticos (+, -, *, / e %). Os módulos podem ser calculados também com mod e a divisão inteira é feita com o operador div.

    Veja um exemplo:

    
    select nome, carga * 2 as 'Carga Dobrada' from cursos;
    
    

    PS: Essa coluna Carga Dobrada não existe, ela aparecerá apenas pra esse select. O operador as (alias) que permite criar ela, é como um "apelido" pra coluna.

    Podemos mostrar as mensagens diretamente no MySQL sem vincular à nenhum banco ou tabela:

    
    select 'Olá Mundo';
    
    

    Ou assim:

    
    select 'Olá Mundo' as 'Mensagem';
    
    

    Dessa forma, podemos fazer operações diretas no MySQL, por exemplo:

    
    select 2 * 9 / 3;
    
    

    Ou assim:

    
    select 2 * 9 / 3 as 'Resultado';
    
    

    Outro exemplo:

    
    select nome, totaulas / 3 as 'Total de 1/3 das Aulas' from cursos;
    
    

    Outro cálculo direto, onde retornamos uma divisão inteira e seu resto:

    
    select 10 div 3 as 'Divisão de 10 por 3', 10 mod 3 as 'Resto de 10 por 3';
    
    

    Também temos funções matemáticas no MySQL, por exemplo:

    Método Significado
    ceiling(x) Arredonda x para o inteiro acima
    floor(x) Arredonda x para o inteiro abaixo
    round(x) Arredonda x para o inteiro mais próximo
    pi() Retorna o valor de PI
    pow(x, y) Retorna x elevado a y
    sqrt(x) Retorna a raiz quadrada de x
    sin(x) Seno de um ângulo específico x, em radianos
    concat(x, y) Concatena dois conteúdos, como textos e números
    bin(x) Retorna a representação binária de x
    oct(x) Retorna a representação octal de x
    hex(x) Retorna a representação hexadecimal de x
    md5(x) Retorna o hash MD5 de x
    sha1(x) Retorna o hash SHA1 de x

    Essas funções também podem ser usadas nos valores de uma coluna. Por exemplo:

    
    select nome, ceiling(totaulas / 3) as 'Total de 1/3 das Aulas' from cursos;
    
    

    Funções em MySQL

    Funções e Procedimentos são dos tipos de rotinas armazenadas, parte da especificação SQL. São um pouco similares, mas com aplicações diferentes. São invocadas de formas diferentes também.

    Uma função é usada para gerar um valor que pode ser usado em uma expressão. O valor é geralmente baseado em um ou mais parâmetros fornecidos à função. É executada como parte de uma expressão.

    Para criar uma função, fazemos assim:

    
    create function multi(a decimal(10, 2), b int)
    returns int return a * b;
    
    

    PS: Note que as variáveis a e b são locais.

    E para executar ela:

    
    select multi(2.5, 4) as 'Resultado';
    
    

    E da mesma forma, podemos usar essa função em dados armazenados, assim:

    
    select nome, multi(carga, 3) as 'Carga Triplicada' from cursos where idcurso = 2;
    
    

    Para excluir uma função, basta usar o comando drop, assim:

    
    drop function multi;
    
    

    Basicamente, as funções retornam valores, diferente dos procedimentos, que não retornam nada.

    Procedimentos Armazenados Básico

    Um procedimento armazenado é uma sub-rotina disponível para aplicações que acessam sistemas de bancos de dados relacionais. Podem ser usadas para validação e dados, controle de acesso, execução de declarações SQL complexas e outras situações.

    Para isso, criamos uma variável local chamada varId, que pegará como parâmetro a id do curso, assim:

    
    create procedure ver_carga(varid smallint)
    select nome, concat('A Carga é ', carga) as 'Carga Total' from cursos where idcurso = varid;
    
    

    PS: O concat fará a concatenação da frase escrita com o dado do banco.

    Para invocar o procedimento, fazemos assim:

    
    call ver_carga(3);
    
    

    E para excluir, fazemos assim:

    
    drop procedure ver_carga;
    
    

    Blocos Begin End

    Os blocos begin e end são contêineres usados para delimitar blocos de comandos a serem executados pela função ou store procedure. Cada declaração aninhada possuí um delimitador (;), Um bloco begin pode ser aninhado dentro de outros blocos.

    Porém, o delimitador de ponto e vírgula pode ser problemático pois, ao ser encontrado em um procedimento ou função, ela finaliza imediatamente. É uma espécie de alias para o comando go. Devemos então mudar esse "atalho" e, para isso, usamos o comando delimiter para criar rotinas com declarações compostas.

    Veja um exemplo abaixo:

    
    delimiter $$
    create function aumenta_carga(car decimal(10, 2), porc decimal(10, 2))
    returns decimal(10, 2)
    begin
        return (car + car) * porc / 100;
    end$$
    delimiter ;
    
    

    No código acima, o delimiter define que ele deve substituir o ponto e vírgula pelos dois cifrões (ou qualquer outro caracter definido por nós). As declarações da função ou procedimento vão entre o begin e o end (este definido pelos ois cifrões). No final o delimitador volta a ser o ; pela nova execução do delimiter.

    E para invocar normalmente, fazemos assim:

    
    select aumenta_carga(40, 10) as 'Resultado';
    
    

    O mesmo vale para procedimentos:

    
    delimiter //
    create procedure ver_carga(varid smallint)
    begin
        select nome, concat('A Carga é ', carga) as 'Carga Total' from cursos where idcurso = varid;
    end//
    delimiter ;
    
    

    E para executar, use o mesmo modo:

    
    call ver_carga(4);
    
    

    PS: Exclua todas as funções e procedimentos não utilizados, assim:

    
    drop function aumenta_carga;
    drop procedure ver_carga;
    
    

    Variáveis Locais e Escopo

    O escopo de uma variável diz respeito aos locais onde a variável "existe", ou seja, onde ela pode ser acessada.

    Os níveis de escopo são esses:

    Podemos criar variáveis locais em um procedimento ou função usando uma declaração declare dentro de um bloco begin. A variável pode ser criada e inicializada com um valor, se desejado. Ficam disponíveis apenas dentro do bloco onde foram criadas, e em blocos que existem dentro do bloco onde a variável foi criada. Após o bloco ter sido executado e encerrado, a variável é desalocada da memória.

    Veja um exemplo abaixo:

    
    delimiter //
    create function aumenta_aulas(ident decimal(10, 2), porc decimal(10, 2))
    returns decimal(10, 2)
    begin
        declare total decimal(10, 2);
        select totaulas from cursos where idcurso = ident into total;
        return (total + total) * porc / 100;
    end//
    delimiter ;
    
    

    No caso acima, o into faz a atribuição a variável local.

    E para executar, normalmente:

    
    select * from cursos where idcurso = 4;
    select aumenta_aulas(4, 10) as 'Aumento das Aulas';
    
    

    Depois pode excluir essa função também.

    Blocos Condicionais IF, THEN, ELSE E CASE.

    Há dois tipos básicos de blocos condicionais, com if, elseif, else e endif, e con case, when, then, else e end case.

    Veja um exemplo básico de uso:

    
    delimiter //
    create function calcula_aula(carg decimal(8, 2))
    returns decimal(8, 2)
    begin
        declare aultot decimal(8, 2);
        if carg < 20 then
            set aultot = 30;
        elseif carg < 50 then
            set aultot = 60;
        elseif carg < 80 then
            set aultot = 100;
        else
            set aultot = 150;
        end if;
        return aultot;
    end//
    delimiter ;
    
    

    PS: O Else if e o Else não são obrigatórios.

    E para executar normalmente, fazemos assim:

    
    select calcula_aula(50) as 'Total de Aulas';
    
    

    Podemos fazer com case também, dessa forma:

    
    -- Primeiro exclua a função anterior:
    
    drop function calcula_aula;
    
    -- E crie novamente com o case, assim:
    
    delimiter //
    create function calcula_aula(carg decimal(8, 2))
    returns decimal(8, 2)
    begin
        declare aultot decimal(8, 2);
        case
        when carg < 20 then
            set aultot = 30;
        when carg < 50 then
            set aultot = 60;
        when carg < 80 then
            set aultot = 100;
        else
            set aultot = 150;
        end case;
        return aultot;
    end//
    delimiter ;
    
    

    O Case geralmente é utilizado quando existem muitas condições.

    Exclua a função caso não a utilize mais.

    Estruturas de Repetição - Loop

    Um bloco iterativo é um bloco de código que é executado repetidamente por um comando especial até que uma condição de parada o interrompa. Um bloco iterativo pode ser aninhado com outros.

    O MySQL possui três tipos básicos de blocos iterativos, loop, repeat e while

    Veja um exemplo básico de uso de loop:

    
    delimiter //
    create procedure acumula(limite int)
    begin
        declare contador int default 0;
        declare soma int default 0;
        laco_teste: loop
            set contador = contador + 1;
            set soma = soma + contador;
            if contador >= limite then
                leave laco_teste;
            end if;
        end loop laco_teste;
        select soma as 'Soma Total do Loop';
    end//
    delimiter ;
    
    

    PS: O leave interrompe o laço, é como o break.

    E para executar:

    
    call acumula(10);
    
    

    Depois exclua o procedimento criado.

    Estrutura de Repetição - Repeat

    Também podemos usar o repeat para criar laços, dessa forma:

    
    delimiter //
    create procedure acumula_repita(limite tinyint unsigned)
    begin
        declare contador tinyint unsigned default 0;
        declare soma int default 0;
        repeat
            set contador = contador + 1;
            set soma = soma + contador;
        until contador >= limite
        end repeat;
        select soma as 'Soma Total do Repeat';
    end//
    delimiter ;
    
    

    E para executar:

    
    call acumula_repita(10);
    
    

    PS: Como o contador é incrementado antes do teste condicional, um valor como 0, ao ser passado, resulta em valor errado. Na verdade, ele garante pelo menos a execução uma vez, independente da condição.

    Podemos usar um rótulo no bloco begin, para podermos "tratar" esse erro num if, e usar o leave com o nome desse rótulo para sair do bloco, assim:

    
    -- Primeiro exclua o procedimento anterior:
    
    drop procedure acumula_repita;
    
    -- E crie novamente, assim:
    
    delimiter //
    create procedure acumula_repita(limite tinyint unsigned)
    main: begin
        declare contador tinyint unsigned default 0;
        declare soma int default 0;
        if limite < 1 then
            select 'O valor deve ser maior que zero!' as 'Erro';
            leave main;
        end if;
        repeat
            set contador = contador + 1;
            set soma = soma + contador;
        until contador >= limite
        end repeat;
        select soma as 'Soma Total do Repeat';
    end//
    delimiter ;
    
    

    Exclua o procedimento se não usar mais.