MYSQL – Usando variáveis

Olá gente. Espero que tenham gostado do meu último artigo. Dessa vez vou falar sobre um recurso menos conhecido. Vamos lá!

O MySQL possui um recurso que até alguns dias atrás achava inútil. Entretanto salvou minha vida num relatório que tive de gerar. Por isso resolvi escrever este artigo para
mostrar funcionamento das variáveis no MySQL.

Declarar variáveis no MySQL é simples, encontrar um modo de usá-las é mais complicado.

Para declarar uma variável basta utilizar a sintaxe:

@variavel:=valor

Vamos testar esta sintaxe:

mysql> select @dt:=1;
+———+
| @dt:=1 |
+———+
| 1
+———+

Você deve ter feito a mesma coisa que eu quando vi isso. “Onde eu vou usar este recurso?”

Bom, vou apresentar a solução onde utilizei este recurso, e vocês poderão decidir se este recurso pode ser útil no seu dia a dia ou não.

Utilizo aqui o MySQL 4.1.8, que possui o recurso de subqueries, utilizado nesse relatório.

1ª Parte:

A primeira parte do relatório é a parte fácil. Um select simples utilizado para buscar dados de uma tabela e apresentá-los na tela.

SELECT
conta as Cod,
tit as Titulo,
dte as Emissão,
dtv as Vencimento,
vlr as Valor,
dtp as Pagamento
FROM contas
WHERE (dtp is null or dtp=’0000-00-00′) and cliente = 5896
ORDER BY dtv ASC

O select acima trás os dados referentes aos boletos de cobrança do cliente 5896 que não foram pagos, conforme mostrado abaixo.

+—–+———————+————–+—————+———-+—————+
| Cod | Titulo
| Emissão     | Vencimento | Valor
| Pagamento |
+—–+———————+————–+—————+———-+—————+
| 151 | BOLETO 01/2005 | 2005-01-03 | 2005-01-10 | 680.00
| 0000-00-00 |
| 1     | Boleto 02/2005
| 2005-02-01 | 2005-02-05 | 1483.28 | NULL
|
+—–+———————+————–+—————+———-+————–+

2ª Parte.

Até aqui tudo certo, e muito fácil. Entretanto para concluirmos o relatório será necessário mostrar se o cliente recebeu ou não o boleto. Após a geração do boleto, é enviado um email para o cliente com o link de onde o boleto está, ao visualizar o boleto o cliente aciona um script que grava em uma tabela o dia, hora e data de vencimento do boleto, bem como seu código de cliente. Assim na tabela emailslidos temos os registros:

+——-+————————–+—————+——————+——+
| id        | lido
| dtv               |
ip                      |
cli    |
+——-+————————–+—————+——————+——+
| 00001 | 2005-03-01 11:43:01 | 2005-03-05 | 201.6.100.118 | 5942 |
+——-+————————–+—————+——————+——+

O nosso relatório deve apresentar, além dos registros da primeira parte, uma coluna contendo a data e hora da visualização do boleto caso este tenha sido visto.

À primeira vista, a utilização de um Join seria o bastante, entretanto não consegui encontar um solução plausível. Sendo assim, pensei em usar subqueries. Aí apareceu
outro problema.

Além de saber o código do cliente, seria necessário saber a data de vencimento de cada boleto, para identificar a data e hora de leitura do boleto certo. Veja o select abaixo.

SELECT
conta as Cod,
tit as Titulo,
dte as Emissão,
dtv as Vencimento,
vlr as Valor,
dtp as Pagamento ,

(select lido from emailslidos where cliente=5896
and dtv=????-??-?? order by DATE_FORMAT(lido,’%h:%i:%s %Y-%m-%d’)
desc limit 1) as lido

FROM contas
WHERE (dtp is null or dtp=’0000-00-00′) and cliente=5896
ORDER BY dtv ASC

Note que coloquei um subquery que equivale a um campo (lido) da minha consulta principal. Se o único parâmetro necessário fosse o código do cliente, um join teria resolvido e no caso de subqueries, a nossa consulta acima estaria resolvida. Entretanto, faz-se necessário a utilização do campo dtv (data de vencimento) que vai justamente identificar o boleto. “E de onde virá o valor do Campo data de vencimento?”.

Vamos separar a select:

SCT1 = SELECT conta as Cod,tit
as Titulo,dte as Emissão,dtv as Vencimento,vlr as Valor,dtp
as Pagamento FROM contas WHERE (dtp is null or dtp=’0000-00-00′)
and cliente=5896 ORDER BY dtv ASC

SCT2 = (select lido from
emailslidos where cliente=5896 and dtv=????-??-?? order by DATE_FORMAT(lido,’%h:%i:%s
%Y-%m-%d’) desc limit 1) as lido

Ou seja, SCT1 é a select principal, e SCT2 é a subquery.

A resposta para a pergunta “E de onde virá o valor do Campo data de vencimento?” está na SCT1. Ou seja, para cada registro apresentado por SCT1, teremos de obter o dtv para usarmos em SCT2.

Usando uma linguagem de programação seria possível fazer uma consulta e depois outra, mais aí estaríamos deixando de aproveitar os recursos do MySQL, sendo assim, vamos à solução com variáveis.

Voltando ao nosso primeiro exemplo e modificando-o um pouco:

mysql> select @dt:=1,@dt+1;

+———+———+
| @dt:=1 | @dt+1  |
+———+———+
| 1 _____| 2 ____ |
+———+———+

Note que setamos a variável dt como 1 em um campo e utilizamos ela no outro campo com sucesso sem que fosse necessário fazer duas consultas, uma para setar e outra para usar a variável. O mesmo princípio pode ser utilizado no nosso relatório.

SELECT
conta as Cod,
tit as Titulo,
dte as Emissão,

@dt:=dtv as Vencimento,
vlr as Valor,
dtp as Pagamento ,

(select lido from emailslidos where cliente=5896
and dtv=@dt
order by DATE_FORMAT(lido,’%h:%i:%s %Y-%m-%d’) desc limit 1)
as lido

FROM contas
WHERE (dtp is null or dtp=’0000-00-00’) and cliente=5896
ORDER BY dtv ASC

Com isso, é possível matar as duas consultas necessárias em uma linguagem de programação em uma única consulta com processamento total em banco.

Fonte: http://imasters.com.br/artigo/3071/mysql/usando-variaveis-no-mysql

Deixe um comentário