Backup zipado automático de toda base MySQL

1 Estrela2 Estrela3 Estrela4 Estrela5 Estrela (Sem votos, vote agora!)
Loading ... Loading ...

Postado por Plinio Cruz em 30 de dezembro de 2009 - Banco de Dados, PHP, Programação | Seja o primeiro a comentar

Na área de sistemas web uma coisa muito importante é o backup da base de dados, afinal um rotina imprópria no sistema pode alterar o banco de dados de forma errada comprometendo a integridade dos dados ou mesmo a consistência das informações. Além disso nenhuma empresa de hospedagem está livre de um problema sério com um servidor que coloque tudo a perder e como muitas não tiram backup podem criar um grande transtorno para o seu cliente.

Nós, da Trio Interativa, desenvolvemos muitos sistemas de gestão de eventos, muitas vezes, durante o processo de inscrições eletrônicas fazemos de três a quatro backup da base do cliente por dia. Além disse, trabalhamos muitas vezes nos sistemas enquanto são utilizados, ou seja, sempre estamos no risco, um código impróprio e podemos mudar tudo na base, então sempre que atualizamos um novo sistema fazemos backup da base também e os outros que normalmente fazemos ao longo do dia nos ajuda na detecção de erros e possíveis inconsistências nos dados.

Com o crescimento do número de clientes e os inúmeros eventos ocorrendo simultaneamente procuramos uma forma de fazer backup de forma rápida, eficiente e que fosse padronizada. Nas muitas pesquisas que fiz achei a uma rotina excelente do Fabio Berbet de Paula, fiz algumas interações no código para padronizá-las para nossa realidade e hoje qualquer profissional da TRIO tem um link para cada cliente, onde com a penas um clique fazemos o backup integral da base em um arquivo ZIP, perfeito e de forma íntegra. Tudo muito fácil e rápido. Veja o código com comentários e as interações que fiz.

Antes de mais nada agradeço ao Fabio Berbet o desenvolvimento do sistema. Para fazer o download do sistema e da classe clique aqui!.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
<?
/*
Programa usado para fazer o dump de uma base de dados do MySQL
 
Por: Fabio Berbert de Paula <fabio@vivaolinux.com.br>
     Rio de Janeiro, 26 de Novembro de 2002
link: http://www.vivaolinux.com.br/script/Backup-do-MySQL-via-PHP
 
Livres Adaptações: Plínio Cruz - Clube da Informática
- Inclusão de arquivo padrão de conexão com a base
- rotina "Lista de Tabelas"
- Padronização do nome do arquivo a ser gravado
 
*/
 
// classe phpzip.inc.php para criar os arquivos compactados
require 'phpzip.inc.php';
 
// variaveis de banco de dados de acordo com o arquivo padrão de conexão
$db_name    = ''; //Nome do banco de dados
$hostdb     = ''; //server do banco de dados
$userdb     = ''; //Usuário de log do banco de dados
$passdb     = ''; //senha do usuário do banco de dados
 
///////////////////////////////////////////////////////////////////////////////////////////////////
//Vamos montar a litas das tabelas do banco de dados escolhido
//Essa rotina foi incluída a original do Fábio, pois antes tínhamos que nomear as tabelas que
//queríamos guardar. Com a nova rotina ele faz o backup do banco como um todo, não precisando
//atualizar o sistema cada vez que você altera a base de dados
///////////////////////////////////////////////////////////////////////////////////////////////////
 
$nome = $db_name;
$link = mysql_connect("$hostdb","$userdb","$passdb");
$resultado_tabelas = mysql_list_tables($nome);
$qntd_tabelas = @mysql_numrows($resultado_tabelas);
if($qntd_tabelas == 0)
    {
      print "<li>Nenhuma tabela foi encontrada neste banco de bados</li>";
      die;
      //Assim "mato" o sistema quando existe um erro
    } else {
              //Aqui vamos criar a rotina para montar a listagem de tabelas
              for ($i = 0; $i < $qntd_tabelas; $i++)
                 {
                    //Temos que determinar as tabelas que não precisam de backup
                    //no meu caso pode ser tabelas como crm, cep, cidade, estado, etc.
                    //No exemplo não faremos backup da "cep" e concatemos as restantes
                    if (mysql_tablename($resultado_tabelas, $i)!='cep')
                    { $tabelas[]= mysql_tablename($resultado_tabelas, $i); };
                 };
              //Temos a array de tabelas pronta
 
           };
 
// as tabelas que quero
//$tabelas = array ('artigos','assuntos'); - Original da rotina do Fabio, onde você montava o array manualmente
//com as tabelas que desejava, a rotina acima faz automaticamente só isso
 
$tempdir = "/tmp"; // diretorio temporario
//$filename = 'sql.'.time().'.txt'; - Modo do Fabio de construir o nome do arquivo
$data = date("dmyhi",time());
$filename = 'nomedocliente.'.$data.'.txt';
//Inclui o nome do banco de dados no nome e a data completa
//Isso porque trabalho com phpmyadmin e MySqlFront e os dois trabalham com essa extensão
//o conteúdo é o mesmo, portanto não fará diferença na hora da gravação
//Na minha opinião facilita para aramazenamento de vários clientes na mesma pasta no servidor local
 
// variaveis do sistema
$incluir_insert = 1; // imprime os INSERT's tambem
 
// ----------------------------------------------------
// BLOCO PRINCIPAL
// conectar ao banco de dados
$con = mysql_pconnect($hostdb,$userdb,$passdb);
mysql_select_db($db_name);
 
// imprimir tipo do documento na tela
 
// imprimir o dump do banco de dados
//chdir($tempdir);
$fp = fopen($filename,"w");
for ($x=0; $x<count($tabelas); $x++) {
   $saida = getTableDef($db_name, $tabelas[$x], "\n");
   fputs($fp,$saida."\n\n");
 
   if ($incluir_insert) {
      getTableContentFast($db_name, $tabelas[$x], '', '');
      fputs($fp,"\n\n");
   }
}
fclose($fp);
 
// gerar o arquivo zipado
$zipname = ereg_replace("txt$","zip",$filename);
$zip = new PHPZip();
$files[]=$filename;
$zip -> Zip($files, $zipname);
 
$tamanho = filesize($zipname);
 
// imprimir arquivo p/ download
header("Content-Type: application/zip");
header("Content-Length: $tamanho");
header("Content-Disposition: attachment; filename=$zipname");
header("Content-Transfer-Encoding: binary");
 
// abrir e enviar o arquivo
$fp = fopen("$zipname", "r");
fpassthru($fp);
fclose($fp);
 
// remover os arquivos temporarios
//unlink($filename);
unlink($zipname);
 
// FIM DO PROGRAMA
// --------------------------------------------------------
 
 
// --------------------------------------------------------
// PROCEDIMENTOS - Baseado no csdigo do phpmyadmin
function sqlAddslashes($a_string = '', $is_like = FALSE) {
  if ($is_like) {
    $a_string = str_replace('\\', '\\\\\\\\', $a_string);
  } else {
    $a_string = str_replace('\\', '\\\\', $a_string);
  }
  $a_string = str_replace('\'', '\\\'', $a_string);
 
  return $a_string;
} // end of the 'sqlAddslashes()' function
 
 
function backquote($a_name, $do_it = TRUE) {
  if ($do_it && PMA_MYSQL_INT_VERSION >= 32306 && !empty($a_name)
      && $a_name != '*') {
 
     if (is_array($a_name)) {
        $result = array();
        reset($a_name);
        while(list($key, $val) = each($a_name)) {
           $result[$key] = '`' . $val . '`';
        }
        return $result;
     } else {
        return '`' . $a_name . '`';
     }
  } else {
     return $a_name;
  }
} // end of the 'backquote()' function
 
/**
* Returns $table's CREATE definition
*
* @param   string   the database name
* @param   string   the table name
* @param   string   the end of line sequence
*
* @return  string   the CREATE statement on success
*
* @global  boolean  whether to add 'drop' statements or not
* @global  boolean  whether to use backquotes to allow the use of special
*                   characters in database, table and fields names or not
*
* @see     PMA_htmlFormat()
*
* @access  public
*/
function getTableDef($db, $table, $crlf) {
   global $drop;
   global $use_backquotes;
   global $con;
 
   $schema_create = '';
   if (!empty($drop)) {
      $schema_create .= 'DROP TABLE IF EXISTS ' .
      backquote($table) . ';' . $crlf;
   }
 
   // For MySQL < 3.23.20
   $schema_create .= 'CREATE TABLE ' .
   backquote($table) . ' (' . $crlf;
 
   $local_query   = 'SHOW FIELDS FROM ' . backquote($table) . ' FROM '
   . backquote($db);
 
   $result = mysql_query($local_query,$con);
 
   while ($row = mysql_fetch_array($result)) {
      $schema_create     .= '   ' .
      backquote($row['Field'])
      . ' ' . $row['Type'];
 
      if (isset($row['Default']) && $row['Default'] != '') {
           $schema_create .= ' DEFAULT \'' .
           sqlAddslashes($row['Default']) . '\'';
      }
 
      if ($row['Null'] != 'YES') {
           $schema_create .= ' NOT NULL';
      }
 
      if ($row['Extra'] != '') {
           $schema_create .= ' ' . $row['Extra'];
      }
 
      $schema_create     .= ',' . $crlf;
   } // end while
 
   mysql_free_result($result);
   $schema_create = ereg_replace(',' . $crlf . '$', '', $schema_create);
 
   $local_query = 'SHOW KEYS FROM ' . backquote($table) . ' FROM '
   . backquote($db);
 
   $result = mysql_query($local_query,$con);
   while ($row = mysql_fetch_array($result)) {
       $kname    = $row['Key_name'];
       $comment  = (isset($row['Comment'])) ? $row['Comment'] : '';
       $sub_part = (isset($row['Sub_part'])) ? $row['Sub_part'] : '';
 
       if ($kname != 'PRIMARY' && $row['Non_unique'] == 0) {
           $kname = "UNIQUE|$kname";
       }
 
       if ($comment == 'FULLTEXT') {
           $kname = 'FULLTEXT|$kname';
       }
 
       if (!isset($index[$kname])) {
           $index[$kname] = array();
       }
 
       if ($sub_part > 1) {
           $index[$kname][] = backquote($row['Column_name']) . '(' . $sub_part . ')';
       } else {
           $index[$kname][] = backquote($row['Column_name']);
       }
   } // end while
   mysql_free_result($result);
 
   while (list($x, $columns) = @each($index)) {
       $schema_create .= ',' . $crlf;
       if ($x == 'PRIMARY') {
          $schema_create .= '   PRIMARY KEY (';
       } else if (substr($x, 0, 6) == 'UNIQUE') {
          $schema_create .= '   UNIQUE ' . substr($x, 7) . ' (';
       } else if (substr($x, 0, 8) == 'FULLTEXT') {
          $schema_create .= '   FULLTEXT ' . substr($x, 9) . ' (';
       } else {
          $schema_create .= '   KEY ' . $x . ' (';
       }
       $schema_create .= implode($columns, ', ') . ')';
   } // end while
 
   $schema_create .= $crlf . ');';
 
   return $schema_create;
} // end of the 'getTableDef()' function
 
/**
* php >= 4.0.5 only : get the content of $table as a series of INSERT
* statements.
* After every row, a custom callback function $handler gets called.
*
* Last revision 13 July 2001: Patch for limiting dump size from
* vinay@sanisoft.com & girish@sanisoft.com
*
* @param   string   the current database name
* @param   string   the current table name
* @param   string   the 'limit' clause to use with the sql query
* @param   string   the name of the handler (function) to use at the end
*                   of every row. This handler must accept one parameter
*                   ($sql_insert)
*
* @return  boolean  always true
*
* @global  boolean  whether to use backquotes to allow the use of special
*                   characters in database, table and fields names or not
* @global  integer  the number of records
* @global  integer  the current record position
*
* @access  private
*
* @see     PMA_getTableContent()
*
* @author  staybyte
*/
function getTableContentFast($db, $table, $add_query = '', $handler) {
   global $use_backquotes;
   global $rows_cnt;
   global $current_row;
   global $con;
   global $fp;
 
  $local_query = 'SELECT * FROM ' . backquote($db) . '.' . backquote($table)
  . $add_query;
 
  $result = mysql_query($local_query,$con);
  if ($result != FALSE) {
     $fields_cnt = mysql_num_fields($result);
     $rows_cnt   = mysql_num_rows($result);
 
     // Checks whether the field is an integer or not
     for ($j = 0; $j < $fields_cnt; $j++) {
         $field_set[$j] = backquote(mysql_field_name($result, $j), $use_backquotes);
         $type = mysql_field_type($result, $j);
         if ($type == 'tinyint' || $type == 'smallint' ||
             $type == 'mediumint' || $type == 'int' ||
             $type == 'bigint'  ||$type == 'timestamp') {
             $field_num[$j] = TRUE;
         } else {
             $field_num[$j] = FALSE;
         }
     } // end for
 
     // Sets the scheme
     if (isset($GLOBALS['showcolumns'])) {
         $fields = implode(', ', $field_set);
         $schema_insert = 'INSERT INTO ' . backquote($table)
         . ' (' . $fields . ') VALUES (';
     } else {
         $schema_insert = 'INSERT INTO ' .
         backquote($table) . ' VALUES (';
     }
 
     $search = array("\x00", "\x0a", "\x0d", "\x1a"); //\x08\\x09, not required
     $replace      = array('\0', '\n', '\r', '\Z');
     $current_row  = 0;
 
     @set_time_limit($GLOBALS['cfg']['ExecTimeLimit']);
 
     // loic1: send a fake header to bypass browser timeout if data
     //        are bufferized - part 1
     if (!empty($GLOBALS['ob_mode']) || (isset($GLOBALS['zip'])
         || isset($GLOBALS['bzip']) || isset($GLOBALS['gzip']))) {
         $time0 = time();
     }
 
     while ($row = mysql_fetch_row($result)) {
         $current_row++;
         for ($j = 0; $j < $fields_cnt; $j++) {
            if (!isset($row[$j])) {
                 $values[] = 'NULL';
            } else if ($row[$j] == '0' || $row[$j] != '') {
                 // a number
                 if ($field_num[$j]) {
                     $values[] = $row[$j];
                 } else {
                    // a string
                    $values[] = "'" . str_replace($search, $replace,
                    sqlAddslashes($row[$j])) . "'";
                 }
           } else {
              $values[] = "''";
           } // end if
        } // end for
 
        // Extended inserts case
        if (isset($GLOBALS['extended_ins'])) {
            if ($current_row == 1) {
               $insert_line  = $schema_insert . implode(', ', $values) . ');';
            } else {
               $insert_line  = '(' . implode(', ', $values) . ');';
            }
        } else {
        // Other inserts case
           $insert_line = $schema_insert . implode(', ', $values) . ');';
        }
        unset($values);
 
        // Call the handler
        fputs($fp,$insert_line . "\n");
 
        // loic1: send a fake header to bypass browser timeout if data
        //        are bufferized - part 2
        if (isset($time0)) {
            $time1 = time();
            if ($time1 >= $time0 + 30) {
               $time0 = $time1;
               header('X-pmaPing: Pong');
            }
        } // end if
     } // end while
  } // end if ($result != FALSE)
  mysql_free_result($result);
 
  return TRUE;
} // end of the 'getTableContentFast()' function
?>

Locação de Fitas de Vídeo com Delphi

1 Estrela2 Estrela3 Estrela4 Estrela5 Estrela (Sem votos, vote agora!)
Loading ... Loading ...

Postado por Plinio Cruz em 27 de outubro de 2009 - Banco de Dados, Delphi, Downloads, Programação | Seja o primeiro a comentar

Jackson Pires, o colaborador dos tutoriais mais completos de Delphi do Clube da Informática, volta a presentear nossos visitantes com um curso completo para desenvolvimento de um projeto de Locação de Fitas de Vídeo.

O arquivo PDF é ricamente recheado de imagens e  muito bem detalhado. Serve de guia não só para a sua aplicação primária, mas como consulta para qualquer sistema de gerenciamento de banco de dados, pois trata das principais ferramentas necessárias para um sistema de gestão de dados.

O nível de detalhamento que leva o leitor do momento de criação das pastas, passando pela criação de menus e tabelas até chegar ao ponto de finalização do projeto e os relatórios.

Obrigado Jackson pela colaboração!

Delphi + MySql: Fazendo Funcionar

1 Estrela2 Estrela3 Estrela4 Estrela5 Estrela (Sem votos, vote agora!)
Loading ... Loading ...

Postado por Plinio Cruz em 19 de junho de 2009 - Banco de Dados, Delphi, Programação | Seja o primeiro a comentar

Introdução

Duas ferramentas. Duas tecnologias que podem ser combinadas, usadas e aperfeiçoadas.

Delphi, linguagem visual utilizando a linguagem Pascal.

MySql, sistema de gerenciamento de banco de dados versátil que utiliza a linguagem padrão SQL.

Os programadores que utilizam o Delphi o conhecem, pois o utilizam freqüentemente, mas o MySql que é tem uma excelente rapidez em sua base de dados, é algo, hoje em dia, casualmente utilizado. Veremos mais adiante como fazer essa dependência entre as duas poderosas tecnologias.

Início

Para começarmos a trabalhar, baixe o MySql em sua mais nova versão em http://dev.mysql.com/downloads/.

Depois de instalado, em versão zip ou simplesmente instalado como um programa qualquer, acesse o diretório bin que está localizado onde você instalou o MySql. Abra o Prompt de comando juntamente com o Prompt do MySql para criarmos nosso banco de dados. Veja a Figura 1.

Digite na tela do MySql, o contexto que segue abaixo.

mysql> create database mydelphi;

Se aparecer a mensagem abaixo, está tudo certo, e assim poderemos prosseguir.

Query OK, 1 row affected (0.02 sec)

Agora, criaremos nossa tabela. Lembrando, que o MySql é igual a qualquer outro banco, em sua sintaxe SQL. Após cada linha aperte a tecla Enter em seu teclado.

mysql>  use mydelphi;

Database changed

mysql> create table usuarios(

->     id int(5) not null auto_increment primary key,

->     nome varchar(20) not null,

->     email varchar(30) not null,

->     comentario text not null

->     );

Query OK, 0 rows affected (0.11 sec)

Até aqui, está tudo certo, iremos inserir agora o conteúdo na tabela, também pelo Prompt de comando.

Novamente, veja abaixo como prosseguir para inserir informações na tabela. Após cada linha aperte a tecla Enter em seu teclado. 

mysql>  insert into usuarios (nome,email,comentario) values (‘Orlando Junior’,’kurt1022@gmail.com’,’Delphi+MySql é realmente muito bom’);

mysql>  insert into usuarios (nome,email,comentario) values (‘Zé’,’ze_zinho@zemail.com.br’,’Eita sô! Num é que esse sistema pega mesmo.’);

mysql>  insert into usuarios (nome,email,comentario) values (‘’ABC,’abc@def.com.br’,’abcdefghijlmnopqrstuvxyz’);

mysql>quit

Saia do prompt.

Base de Dados

Antes de continuarmos, baixe o componente ODBC para utilizarmos juntamente com o Delphi; em http://www.mysql.com/products/connector/odbc/. Instale-o normalmente.

Acesse o BDE Administrator e crie uma nova coluna com o nome de mydelphi, selecionando o Driver ODBC do MySql; em seguida, salve.

Veja abaixo como deve ficar a configuração da nossa nova coluna.

No menu do administrador de bancos acesse o ODBC Administrator. Adicione o driver do MySql que baixamos. Após criá-lo, irá abrir uma nova janela de configuração.

Na aba Login, digite mydelphi em Data Source Name; em Server, digite localhost; em user digite  root e em Database selecione nosso banco de dados, em seguida teste a conexão. Se exibir uma mensagem dizendo que a conexão foi realizada com êxito, poderemos prosseguir.

Salve todas as suas operações no BDE Administrator e saia dele.

Já no Delphi, personalize sua aplicação ao seu modo.

Adicione o componente ADOConnection na aba ADO. Clique em Build com a opção Use Connection String selecionada.

Para especificar nossa fonte de dados, na aba Conexão, clique em atualizar e na caixa de texto ao lado selecione a fonte myodbc. Em nome de usuário digite root, e teste a conexão. Se tudo estiver certo, poderemos prosseguir com êxito.

No Object Inspector, altere para True na opção Connected, em seguida confirme na janela que irá aparecer. Em DefaultDatabase, selecione mydelphi.

Insira o componente ADOTable e conecte-o com o outro componente; em seguida selecione nossa tabela e ative o componente.

Clique duas vezes no componente ADOTable, e com o botão direito do mouse adicione todos os campos da tabela do banco de dados. Ligue-os corretamente de acordo com seu nome e seu campo em KeyFields.

Em seguida ative o componente. Adicione o componente Data Source e selecione o DataSet no mesmo.

Para continuarmos, adicione 4 Labels com os respectivos subtítulos:

  • ID:
  • Nome:
  • E-mail:
  • Comentário:

Agora, adicione 3 DBEdits e apenas um DBMemo, juntamente com um controlador de formulários, o DBNavigator, todos localizados na aba Data Controls.

Na aba Standard, insira em nosso form 3 Buttons, com os respectivos subtítulos seguidos de seus códigos, adicionando-os entre begin e end; no evento OnClick da aba Events no Object Inspector.

- Novo

AdoTable.Append;

Self.Activate;

- Inserir

AdoTable.Append;

AdoTable.Post;

- Excluir

ADOTable.Delete;

Após a inclusão dos códigos, selecione os campos de inclusão e o navegador de formulários; e segurando a tecla shift, selecione o DataSource no Object Inspector.

Ligue corretamente os campos com seu nome respectivo de acordo com o DataField. Com isso, você irá perceber que os valores que colocamos no prompt de comando irão começar a aparecer no form principal.

Veja abaixo, como deverá ficar nosso programa.

Orlando da Silva Junior 

Quando Utilizar Inner, Left, Right e outras variações do Join no MySQL – Parte 2

1 Estrela2 Estrela3 Estrela4 Estrela5 Estrela (1 votos, média: 5,00)
Loading ... Loading ...

Postado por Plinio Cruz em 16 de junho de 2009 - Banco de Dados, Programação | Leia o primeiro comentário

No nosso primeiro artigo sobre o assunto falamos sobre o básico das amarrações de tabelas no MySQL, falamos sobre o Inner Join e conhecemos assim suas limitações. Agora começaremos utilizar os comandos a favor de um programação estruturada e voltada para a administração de dados de uma forma mais eficiente. Utilizaremos o mesmo caso e as mesmas tabelas do primeiro artigo para propor nossos problemas e assim mostrar de forma prática as soluções.

Left Join

Vamos partir do ponto que um sistema que é desenvolvido e utilizado para a administração de um evento ele é feito para operar e auxiliar os usuários nas exceções, ou seja, se o sistema funcionar do modo planejado, as pessoas entrarão no site, farão as inscrições, pagarão a quantia referente a sua categoria e assim que confirmado o pagamento mudarão de status dentro do sistema automaticamente. Mas como administrar as exceções e como encontrá-las? Para isso utilizaremos o Left Join nas amarrações das ferramentas que faremos para tratar essa inscrições que saíram por algum motivo da normalidade.

No nosso caso, uma inscrição que não tenha um status correspondente ao evento ou ainda uma categoria inválida, deixaria os dados inconsistentes e não teríamos por exemplo um total de pagamentos por categoria, ou até mesmo não controlaríamos o status de “inscrito e pago” corretamente. Esse é uns poucos exemplos de casos que o Inner Join deixaria de lado e tornaria nosso sistema de adminsitração de eventos falho.

Modo sistemático da amarração com left join. A tabela "inscrições" a esquerda (left) das outras duas.

Modo sistemático da amarração com left join. A tabela

Um modo de controlar esse problema é utilizando o Left Join nas amarrações das tabelas, no nosso caso utilizaremos com as tabelas de status e categoria, pois o Left Join preserva todas as linhas da tabela da esquerda (“inscricoes”), descartando as da direita (“status” e “categoria”) quando não há correspondência. No nosso caso os registros que não tenham correpondências aparecerão com valores em branco ou “null”, dependendo da configuração utilizado nos campos. Veja como ficaria a linha de código.

SELECT
  *
FROM
  `cadastrogeral` INNER JOIN
  `inscricoes` ON `cadastrogeral`.`codigo` = `inscricoes`.`cadastro` LEFT JOIN
  `categoria` ON `categoria`.`codigo` = `inscricoes`.`categoria` LEFT JOIN
  `status` ON `status`.`codigo` = `inscricoes`.`status`;

Por exemplo, para saber quais registros estão insconsistentes no quisito “status” basta criar uma ferramenta que busque dentro do universo selecionado o valor para “status” em branco ou com valor “null”, assim só teríamos inscrições que por alguma razão qualquer não teria um status válido no sistema, assim o usuário admninistraria na própria ferramenta colocando o status correspondente ou ainda teria como, de forma direta, procurar saber o ocorrido na inscrição do indivíduo para tomar as providências e com isso teríamos um sistema de automação perfeito, onde o usuário adminsitraria somente as instruções.

Quando Utilizar Inner, Left, Right e outras variações do Join no MySQL – Parte 1

1 Estrela2 Estrela3 Estrela4 Estrela5 Estrela (Sem votos, vote agora!)
Loading ... Loading ...

Postado por Plinio Cruz em 14 de junho de 2009 - Banco de Dados, Programação | Leia o primeiro comentário

Sempre tive muitas dúvidas sobre a utilização do “join” na amarração das tabelas dos banco de dados feitos pelo meu sistema, por vezes utilizava por intuição e por outras na velha tentativa e erro, como gosto de saber o que estou fazendo e de me sentir seguro quanto estou programando, fui estudar um pouco mais sobre o assunto e trago de forma prática um pouco dos detalhes que observei e que são de grande utilidade para quem está programando.

No sistema que vou utilizar de exemplo, tenho quatro tabelas que utilizo para administrar inscrições em eventos para um cliente. Temos então a tabela “cadastrogeral” onde tenho os dados dos participantes (nome, telefone, endereço, e-mail, etc), a tabela “categoria” onde cadastro as categorias com os respectivos preços referente a cada evento que o cliente organiza, a tabela “status” onde tenho os tipos de status de controle do participante em determinado evento (inscrito e não pago, inscrito e pago, retirado do evento, etc) e por fim tenho a tabela “inscricoes” onde controlo pelo id do cadastro geral em qual ou quais eventos aquele participantes está, que categoria está inscrita e em que status o mesmo se encontra.

Nesse cenário é fundamental que eu tenha uma amarração muito bem feita para criar ferramentas que ajudem meu cliente a agrupar inscrições por categoria, a achar indivíduos inscritos e que ainda não estão com suas inscrições pagas, quais categorias estão sendo mais procuradas, se existe alguma inscrição insconsistente, ou seja, a pessoal se inscreveu e não tem categoria determinada e outros fatores a serem pesquisados em uma organização de evento.

Vamos ver o primeiro tipo de amarração, utilizando todas as tabelas e para verificar as inscrições válidas, ou seja, completas, com associação na tabela de inscrição e com categoria e status existentes. Vejamos o código:

SELECT
  *
FROM
  `cadastrogeral` INNER JOIN
  `inscricoes` ON `cadastrogeral`.`codigo` = `inscricoes`.`cadastro` INNER JOIN
  `categoria` ON `categoria`.`codigo` = `inscricoes`.`categoria` INNER JOIN
  `status` ON `status`.`codigo` = `inscricoes`.`status`;

Para exemplificar sistematicamente o comando acima veja o quadro a seguir:

Clique na imagem para ampliar

Nesse exemplo só serão exibidas as inscrições que tenham correpondências em todas as tabelas, temos que ter uma pessoa inscrita no cadastro geral com uma inscrição criada para um evento na tabela inscrições em uma categoria existente e com um status também existente. Só nessa condição teremos o registro exibido. Uma função que serve somente para verificação de inscrições no evento da forma correta.

Qualquer coisa que fuja dessa condição será ignorada na exibição dos dados. Basta que apenas uma condição não seja atendida para o registro não aparecer, por exemplo: o indivíduo está inscrito no evento, em uma categoria existente só que o sistema não foi progamado de forma correta e a inscrição não recebeu um status, está igual a “null” ou ainda “0″ na tabela “inscricoes” e esse código não tem correspondência na tabela de status, o registro não será exibido no comando acima, o que vai impossibilitar o administrador do evento de ficar sabendo do ocorrido e tomar as providências necessárias.

No próximo artigo veremos o Left Join! Abraço e até lá!