HowTo: MySQL – Como resetar um campo Auto Increament

Tenho uma tabela com uma coluna de auto-incremento para a chave primária. Ao adicionar e/ou excluir registros o valor de auto incremento irá continuar a aumentar.

problema 1:
Se eu tiver 10 registros inseridos e depois deletar 9 dos 10 registros, o próximo valor a ser inserido será 11, não 9.

Solução:
Pode-se executar a seguinte query:

[sql]ALTER TABLE tablename AUTO_INCREMENT = 1[/sql]

Isso irá redefinir o valor do auto-incremento para o maior valor definido +1, assim, o valor de auto-incremento do próximo registro a ser inserido terá início a partir 9, no exemplo dado.

Pode-se utilizar também essa técnica, quando se deseja de fato limpar todos os registros da tabela e recomeçar o auto-incremento.
[sql]
DELETE FROM tablename
ALTER TABLE tablename AUTO_INCREMENT = 1
[/sql]

Problema 2:
Se eu tivesse entrado com 10 registros, e excluido alguns como o  4 e 5 e quero inserir próximo registro como 4 não 11.

Solução:
Execute a seguinte query:
[sql]SET insert_id = 4;
INSERT INTO tablename VALUES (‘blah’, ‘…’);[/sql]

Isto irá adicionar o próximo registro na posição 4.

SET insert_id = # (onde # é o valor do auto-incremento que você quer usar).

PS.: Só é eficaz para a inserções imediatas imediatas, uma por vez.

WP-DownloadManager – Reordenando os Registros na “Unha”

wpmanager

Quem trabalha com WordPress de forma profissional com certeza deve conhecer um plugin chamado WP-DownloadManager, do Lester Chan, um dos mais atuantes desenvolvedores de plugins para WordPress, veja alguns.

Pois bem, o Wp-DownloadManager é uma mão na roda para disponibilizar arquivos para download, permite criar categorias, ordenar a disponibilização dos arquivos e ainda faz estatísticas de download.

Tenho usado ele na intranet de um dos meus empregadores, com sucesso. Mas vamos aos problemas que precisei solucionar.

1.  Temos diversas categorias de downloads, e acertamos que a ordem que mostraríamos os arquivos aos usuários era os mais novos primeiros, ordenados pelo file_id dos arquivos, veja abaixo a tabela do plugin.

[sql]

CREATE TABLE  `wp_downloads` (
`file_id` int(10) NOT NULL auto_increment,
`file` tinytext NOT NULL,
`file_name` text NOT NULL,
`file_des` text NOT NULL,
`file_size` varchar(20) NOT NULL default ”,
`file_category` int(2) NOT NULL default ‘0’,
`file_date` varchar(20) NOT NULL default ”,
`file_updated_date` varchar(20) NOT NULL default ”,
`file_last_downloaded_date` varchar(20) NOT NULL default ”,
`file_hits` int(10) NOT NULL default ‘0’,
`file_permission` tinyint(2) NOT NULL default ‘0’,
PRIMARY KEY  (`file_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=0 ;

[/sql]

Tudo estava funcionando maravilhas,  os usuários fazem o upload dos arquivos, levando em consideração que os mais antigos devem ser inseridos primeiro, e ai será exibido como planejamos, ficando assim:

277/2009 – Designa Comissão Especial …..
» 42.5 KiB – 5 downloads – 02 de novembro de 2009

276/2009 – Designa Comissão Especial encarregada de elaborar …..
» 41.0 KiB – 3 downloads – 05 de novembro de 2009

275/2009 – Designa o servidor ….l
» 43.0 KiB – 2 downloads – 10 de novembro de 2009

O problema é que como a intranet atual foi migrada de uma versão anterior, onde não existia um CMS, vários arquivos foram inseridos a esmo, e que ao serem exibidos não correspondem a lista descrescente por nome, como no exemplo acima.

Embora que sistema permita mudar isso facilmente, isso não era possível de se fazer, pois iria afetar todas as outras categorias, pois as mudanças de ordenação são globais.

Vejamos a solução:

Primeiro foi dado um Select na tabela WP_DOWNLOADS para retonar o último FILE_ID.

[sql]

SELECT max(file_id) FROM  wp_downloads

[/sql]

retornou: 969

Com o uso de um contador, é possível simular uma contagem sequencial, veja:

[sql]

set @contador:=970;
SELECT (@contador:=@contador+1), wp_downloads.* FROM `wp_downloads` WHERE `file_category`= 10 order by `file_name` asc

[/sql]

Ou seja, a idéia é fazer com que os valores desse SELECT sequencial possa ser aplicado na coluna file_id da tabela wp_downloads.

Com a ajuda de meu amigo Edcley Firmino – o papa do SQL -,  chegamos a decisão de fazer uma Procedure utilizando RowID. Veja como ficou:

[sql]

BEGIN

DECLARE vcontador INT;
declare b,vfile_id int;
DECLARE cursor_1 CURSOR FOR SELECT file_id
FROM wp_downloads WHERE file_category= 10
order by file_name ASC;

DECLARE EXIT HANDLER FOR NOT FOUND SET b=1;
OPEN cursor_1;
set vcontador := 970;
REPEAT
FETCH cursor_1 INTO
vfile_id;
update wp_downloads
set file_id = vcontador
where file_id = vfile_id;
set vcontador := vcontador + 1;

UNTIL b=1 END REPEAT;
CLOSE cursor_1;

END

[/sql]

Pronto, ao executar-mos essa procedure, todos os registros da coluna File_ID foram atualizados, e então foi possível voltar a exibir corretamente os arquivos em ordem decrescente.

Funciona maravilhosamente bem… é isso.

Howto: Corrigindo Charset – LAOP (Linux+Apache+Oracle+PHP)

Howto:  Corrigindo Charset – LAOP (Linux+Apache+Oracle+PHP)
=============================================

Vamos ao cenário:

“Eu possuo um servidor Debian com Apache, PHP, e Client do Oracle 9i entre outras coisas. Na hora de mandar as informações para o banco se a informação contiver acentuação ela grava com erro no banco por exemplo:
Se eu quiser gravar joão no banco fica: joco

Eu ja fiz o teste e realizei um insert direto na base através do sql plus e não deu problema os acentos aparecem, o problema acontece apenas quando eu envio a informação através de uma página PHP.  E o mesmo acontece quando tenta recuperar a informação do Banco.

Tentei mudar o charset da página com:
[html][/html]

Mas mesmo assim as informações apareciam com caracteres estranhos.

Para Acentuação:
Adicione as seguinte linhas no arquivo: /usr/local/apache2/bin/envvars

[html]NLS_LANG=”portuguese_brazil.we8iso8859p1″
export NLS_LANG[/html]

O arquivo envvars pode estar em outro local, depedendo de como foi realizada a instalação, em um dos meus servidores o aquivo estava em:  /etc/apache2/envvars

Provavelmente se as linhas forem adicionadas no /etc/profile o problema também se resolva, porém não testei…

Após isso é so reiniciar o Apache e testar.

Postgresql – Backup e Restaure

  • Backup/Dump uma base

/usr/local/pgsql/bin/pg_dump BASE > arquivo_backup.sql

PS:  você também pode exportar direto para um arquivo compactado:

# pg_dump -U postgres -h localhost –inserts BASE | gzip -c > arquivo_backapiado.gz

  • Importando a base

/usr/local/pgsql/bin/psql -d BASE -f ARQUIVO.sql

Veja como importar arquivo SQL utilizando console PSQL.

psql -d BASEDEDADOS -f ARQUIVO.SQL -U USUARIO

Exemplo:

#su postgres

#psql -d bancoxyz -f meubanco.SQL -U postgres

para ver o que está sendo executado, adicione: -a

Mysql – duplicar coluna

Dica besta, que pode salvar alguém…

Como duplicar o conteúdo de uma coluna de uma mesma tabela de um Banco de Dados?

[sql] update TABELA set ColunaDestino = ColunaOrigem [/sql]

Simples assim.

Há então quer dizer que posso também usar esta técnica para adicionar uma sequencia de valores em colunas? Sim, ai é so fazer assim:

[sql] UPDATE tabela SET coluna=CONCAT(coluna, ‘.jpg’) [/sql]

Howto: Executar dumps extensos com phpMyAdmin

===================================================
Howto: Executar dumps extensos com phpMyAdmin
===================================================

Aqui está um truque simples e conveniente que eu uso muitas vezes para fazer o Dump de scripts  MySQL, contornando as restrições de limites do PHP/Apache  (file upload).

O exemplo abaixo foi realizado utilizando o Vertrigo, mas o procedimento é o mesmo para uma instalação Linux.

1. Vá até o diretório onde esta instalado o seu phpMyAdmin e crie uma pasta chamada “upload”.  Cole qualquer (pode ser vários) scripts SQL que você gostaria de rodar nesta pasta. Desculpe o nome desfocado, mas é por razões de segurança.

screenshot_upload1

2. Abra o arquivo de configuração do phpMyAdmin (config.inc.php). Você o encontrará na raiz da pasta  do diretório phpMyAdmin.
screenshot_config_location1
3.  Edite o config.inc.php na linha do diretório upload, como mostrado abaixo e salve.

screenshot_edit

4. Agora, quando você entrar no phpMyAdmin, você verá uma guia nova listando todos os arquivos que você tenha inserido no diretório  “upload”, criado na etapa 1 acima.
timthumb
Portanto, da próxima vez que você tentar transferir um script SQL grande para um servidor remoto,  tente o truque acima e, em seguida, faça upload dos SQL´s via FTP para dentro da pasta “upload” criada por você e selecione-o a partir da lista que phpMyAdmin apresenta… funciona que é uma maravilha..

Resultado de dois bancos distintos em apenas um SQL

=================================================================
Howto: Como realizar a busca em dois bancos distintos e unir o resultado em apenas um SQL?
=================================================================

Primeiro o problema:
Você precisa fazer uma busca em dois bancos de dados e mostrar o resultado em um lugar só, isso porque você tem partes dos dados em um banco e o restante dos dados em outro banco, e por motivo estrutural, burocrático… sabe-se lá porque…. você não pode unir tudo em um único database.

Solução:
Você pode unir dois resultados (inclusive de drivers/bancos que estejam na mesma conexão) em um unico result, mesclando os dados. Para isso deve-se utilizar a estrutura UNION.

Analisemos a seguinte query:

[sql]
SELECT cod, nome, idade FROM pessoas
SELECT codigo, nome_completo, idade FROM pessoas_nao_cadastradas
[/sql]

Primeiro, você deve ter resultados iguais para cada select, para isso use alias para igualar os resultados.

[sql]
SELECT cod, nome, idade FROM pessoas
SELECT codigo AS cod, nome_completo AS nome, idade FROM pessoas_nao_cadastradas
[/sql]

Agora, basta você usar o UNION entre os dois selects:

[sql]
SELECT cod, nome, idade FROM pessoas
UNION
SELECT codigo AS cod, nome_completo AS nome, idade FROM pessoas_nao_cadastradas
[/sql]

Já, agora você tem o resultado de dois bancos de dados mesclados em um só.

E como fazer um LIKE (WHERE)?

Você deve fazer um WHERE ou nos dois SELECTs ou fazer um SELECT que totaliza os dois:

[sql]
SELECT xyz.* FROM (
SELECT cod, nome, idade FROM pessoas
UNION
SELECT codigo AS cod, nome_completo AS nome, idade FROM pessoas_nao_cadastradas

) xyz WHERE nome = ‘Paulo’
[/sql]

Howto: Localizando e removendo registros duplicados – SQL

Howto:  Como apagar registros duplicados no MySQL.

Existem diversas técnicas para remover duplicidade em um Banco de Dados,  porém pra mim, a solução mais simples é usar UNIQUE INDEX. Veja como funciona…

ALTER IGNORE TABLE ‘tabela‘ ADD UNIQUE INDEX(campos_que_nao_vao_se_repetir);

Exemplo:

ALTER IGNORE TABLE ‘usuario‘ ADD UNIQUE INDEX(email);

Lembrando que após realizar este procedimento, o campo indicado será único, ou seja, não irá permitir mais duplicidade. Você pode até adicionar mais de um campo, simples assim.

Agora, se você quer apenas verificar se existe duplicidade, existe algumas querys simples para isso:

[sql]
SELECT
email,
count(*)
FROM pessoa
WHERE
email <> ”
GROUP BY email
HAVING COUNT(*) > 1
[/sql]
Neste exemplo, será exibido duas colunas, a primeira com os registros que existem duplicados e na segunda o número de registros com a mesma informação.

Outro exemplo:

[sql]
SELECT
email,
nome
FROM
pessoa tab1
WHERE (SELECT count(*) FROM pessoa tab2 WHERE tab2.email = tab1.email) > 1
[/sql]
Neste caso mostra além do registro duplicado outra coluna (nome) que julgar necessário. Ou assim também:

[sql]
SELECT
email,
equipe,
count(*) as total_duplicados
FROM pessoa
WHERE
email <> ” and equipe IN (10,11)
GROUP BY email, equipe
HAVING COUNT(*) > 1
[/sql]

Exibirá os registros duplicados da equipe 10 e 11, informando na última coluna quantas vezes o mesmo encontra-se duplicado.

Simples assim.

Ferramentas para gerar dados de teste

Um dos grandes problemas que nós desenvolvedores enfrentamos quando estamos iniciando uma aplicação Web nova é com o rendimento em etapas iniciais do processo, problemas estes que vão se tornando mais visíveis a medida que temos uma quantidade de dados mais elevado e um número maior de usuários concorrentes.

Para resolver o problema com usuários concorrentes, é possível realizar teste de stress, porém quando se necessita ter um volume de dados elevado para poder provar se a aplicação esta se comportando como esperávamos, o que normalmente se faz é inserir manualmente essas informações, porém para este caso, temos ferramentas bastante úteis:

  • GenerateData: para mim um dos melhores.
  • DBMonster: para gerar dados aleatórios em uma base de dados. Muito completo, porém um pouco mais complexo.
  • CSV Data Generator: baseado em Ruby, gerar arquivos CSV.
  • Datagenerator: Este também gostei bastante por ser bem simples. Permite gerar dados para Mysql, Firebird, Interbase, MSSQL, Oracle, SQLite e PostgreSQL.

No post original, tem a sinopse de outros…
Test (Sample) Data Generators