Fórum Alteração de coluna zerando dados antigos #53315
12/10/2005
0
Precisei fazer algumas alterações em um banco de dados FB 1.5.2, alterando o tamanho de alguns campos. Ocorre que num destes campos do tipo ´String´, se o campo já tiver o tamanho correto, seus dados antigos estão sendo apagados. Como evitar isso? Vejam o exemplo:
OBS: ´campo_a´ originalmente tem o tamanho 2.
------
ALTER TABLE tabela_a
ADD campo_a_temp CHAR(3);
UPDATE tabela_a
SET campo_a_temp = ´0´ || campo_a;
ALTER TABLE tabela_a
DROP campo_a,
ADD campo_a CHAR(3);
UPDATE mov_gravacao
SET campo_a = campo_a_temp;
ALTER TABLE tabela_a
DROP campo_a_temp;
------
O problema ocorre quando ´campo_a´ já tem o tamanho 3. Nesse caso o ´UPDATE´ está tornando todos os valores antigos ´NULL´. A única forma seria utilizar alguma função externa para testar o tamanho do valor atual do campo e somente alterá-lo se for menor do que o pretendido, ou existe alguma função do Firebird que evite a alteração indevida dos campos antigos?
Grato por qualquer orientação!
João Lira.
Joao Lira
Curtir tópico
+ 0Posts
13/10/2005
Afarias
DROP campo_a,
ADD campo_a CHAR(3);
no código acima vc está dropando o campo e criando novamente. nada mais justo q todos os valores fiquem NULLos.
se deseja ALTERAR um campo deve usar ALTER e não DROP, ex:
ALTER TABLE tabela_a
ALTER campo_a TYPE CHAR(3);
T+
Gostei + 0
13/10/2005
Joao Lira
Grato pela resposta. Não conhecia esta variação do ´ALTER´ utilizando o modificador ´TYPE´. Vou testar na minha aplicação.
Com relação às colunas ficando ´NULL´, elas estavam ficando _apenas_ quando o campo _já_ era CHAR(3), e neste comando, especificamente:
UPDATE tabela_a
SET campo_a_temp = ´0´ || campo_a;
Quando se cria um novo campo, depois de DROPá-lo, certamente seus valores ficarão nulos. Ocorre que se a alteração do tamanho do campo já houvesse ocorrido (campo_a [b:178a535bfe]já [/b:178a535bfe]estivesse como VARCHAR(3)), e o comando UPDATE fosse tentado novamente, o erro acontecia, isto é, não apenas aquele registro ficava ´NULL´, como TODOS os demais! Isso que achei estranho, parecendo até um bug. Isso é normal no Firebird?
Grato pela atenção.
João Lira.
Gostei + 0
13/10/2005
Joao Lira
João Lira.
Gostei + 0
14/10/2005
Afarias
x = ´0´ || campo_null; // resulta x = null
T+
Gostei + 0
14/10/2005
Joao Lira
Esse é o problema: o campo não tinha valor NULL. Acompanhe os fatos:
1) O ´campo_a´ inicialmente era um CHAR(2);
2) Foi necessário redimensionar o ´campo_a´ para CHAR(3);
3) Após isso, conforme você pode ver acima, era feita uma concatenação da constante ´0´ com o valor inicial de ´campo_a´ (CHAR(2)) que _sempre_ tinha algum valor de dois caracteres (´02´, por exemplo);
4) Ocorre que aqueles comandos SQL que você viu acima, eventualmente, poderiam ser executados num banco de dados que _já_ estivesse tido o ´campo_a´ convertido para CHAR(3) e com a string completa (´025´, por exemplo);
5) Caso o campo já estivesse com três caracteres, o Firebird estava tornando aquele campo daquele registro NULL. Se _todos_ os registros já estivessem convertidos para CHAR(3) e com o ´0´ concatenado (isto é, com a string cheia), _todos_ os campos ´campo_a´ (CHAR(3)) estavam se tornando NULL!
Assim sendo, minha dúvida é a seguinte: se existir um campo do tipo CHAR(x) e numa concatenação como aquela acima se tentar adicionar um caracter a uma string já cheia, eu pensei que o Firebird fosse simplesmente ignorar a tentativa de acréscimo da string. O que está acontecendo é que ele está tornando aquele campo NULL. Isso era para ser assim mesmo? Se for, terei que sempre testar se a String já está ou não completa?
Espero que a dúvida tenha ficado mais clara agora.
Grato pela atenção.
João Lira.
Gostei + 0
15/10/2005
Firekiller
No caso, como você está concatenando no início, ou seja, se você tinha o valor 003, e concatenasse ficaria 0003,e então o 3 estaria perdido, ou então ele daria um erro de estouro de tamanho, e gravaria nulo.
Então, havendo a possibilidade do campo já ter sido totalmente preenchido, creio que vc terá que verificar o tamanho sim.
Bom, mas me tira uma dúvida, se o campo tinha tamanho 2, como ele pode estar totalmente preenchido com 3 dígitos???
Gostei + 0
15/10/2005
Joao Lira
Com relação ao fato do campo estar preenchido com três dígitos, é que eu fiz um sistema simples de atualização automática do banco de dados, quando preciso, de modo que se o arquivo de ´script´ fosse executado novamente (o sistema de script de autoatualização não está ainda finalizado...), o campo poderia já estar alterado e o erro acontecia.
Ok, utilizarei função que verifique o tamanho da string atual sempre que fizer concatenações do gênero. A dúvida que eu queria tirar do Firebird era essa, sobre a necessidade ou não de se ter de testar o tamanho da string antes de fazer a concatenação.
Grato pela atenção.
João Lira.
Gostei + 0
17/10/2005
Firekiller
Então, o que você pode fazer, é apenas adicionar uma clausula where, verificando o tamanho (where length(campo_a) = 2).
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)