Fórum Alteração de coluna zerando dados antigos #53315

12/10/2005

0

Olá,


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

Joao Lira

Responder

Posts

13/10/2005

Afarias

ALTER TABLE tabela_a
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+


Responder

Gostei + 0

13/10/2005

Joao Lira

Caro AFarias,


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.


Responder

Gostei + 0

13/10/2005

Joao Lira

Onde se lê VARCHAR(3) na mensagem anterior, entenda-se CHAR(3).


João Lira.


Responder

Gostei + 0

14/10/2005

Afarias

Não sei se entendi bem, mas É normal sim no FB que ao concatenar qualquer coisa com NULL o resultado é NULL, ou seja::

x = ´0´ || campo_null; // resulta x = null



T+


Responder

Gostei + 0

14/10/2005

Joao Lira

Caro AFarias,


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.


Responder

Gostei + 0

15/10/2005

Firekiller

Colega Joao Lira,
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???


Responder

Gostei + 0

15/10/2005

Joao Lira

Caro Firekiller,


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.


Responder

Gostei + 0

17/10/2005

Firekiller

Colega, verificar, até que verifica, mas é que como você está concatenando no inicio do campo, ele irá descartar o último dígito, no caso um valor importante da expressão.

Então, o que você pode fazer, é apenas adicionar uma clausula where, verificando o tamanho (where length(campo_a) = 2).


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar