Preencher Lacuna (GAP) em coluna de tabela PostgreSQL
Ola, gostaria de preencher lacunas em uma coluna de uma tabela no banco.
Por exemplo:
.
id | nome
--------
3 | Maria
5 | Beatriz
9 | Helena
.
ao incluir novos registros, os próximos IDs deveriam ser
1,2,4,6,7,8,10...
Já vi alguns exemplos na internet mas todos são falhos
Alguém tem ideia de como fazer isso funcionar?
Por exemplo:
.
id | nome
--------
3 | Maria
5 | Beatriz
9 | Helena
.
ao incluir novos registros, os próximos IDs deveriam ser
1,2,4,6,7,8,10...
Já vi alguns exemplos na internet mas todos são falhos
Alguém tem ideia de como fazer isso funcionar?
Alberto
Curtidas 0
Melhor post
Jair N.
11/05/2018
Boa Tarde, veja algo que fiz a um bom tempo...
--DROP FUNCTION fnc_int_intervalo(VARCHAR, VARCHAR); CREATE OR REPLACE FUNCTION fnc_int_intervalo(tabela VARCHAR, campo VARCHAR) RETURNS integer AS $BODY$ DECLARE intRetorno INTEGER DEFAULT 0; curSQL REFCURSOR; recSQL RECORD; BEGIN OPEN curSQL FOR EXECUTE ''SELECT COALESCE(''|| Campo ||'',0) AS int_cod_atual FROM ''|| Tabela || '' ORDER BY ''|| Campo; LOOP FETCH curSQL INTO recSQL; intRetorno = intRetorno + 1; IF (intRetorno <> recSQL.int_cod_atual) OR (recSQL.int_cod_atual IS NULL) THEN RETURN intRetorno; CLOSE curSQL; EXIT; END IF; END LOOP; CLOSE curSQL; RETURN intRetorno; END; $BODY$ LANGUAGE ''plpgsql'' VOLATILE
GOSTEI 2
Mais Respostas
Alberto
11/05/2018
Eu testei sua funcão, funciona direitinho, mas pelo que vi ela
"varre" a tabela, procurando pela lacuna, o que, em tabelas
com pouco registros nao faz diferença, mas se existir uma tabela
com 1 milhao de registros e nao existir nenhuma lacuna, a funcao
vai ficar num loop de 1 milhao, ate retornar.
.
Eu estava procurando algo mais viável,
como um select mais restrito, com resposta rápida.
.
Mas, mesmo assim, obrigado pela cooperaçao.
"varre" a tabela, procurando pela lacuna, o que, em tabelas
com pouco registros nao faz diferença, mas se existir uma tabela
com 1 milhao de registros e nao existir nenhuma lacuna, a funcao
vai ficar num loop de 1 milhao, ate retornar.
.
Eu estava procurando algo mais viável,
como um select mais restrito, com resposta rápida.
.
Mas, mesmo assim, obrigado pela cooperaçao.
GOSTEI 0
Alberto
11/05/2018
Tive uma ideia sobre o assunto e resolvi implementar:
No caso da tabela abaixo, que é resultado de uma query, temos a coluna "row"
que é o sequencial gerado pela query.
.
row | id | nome
-----------------
1 | 3 | Maria
2 | 5 | Beatriz
3 | 9 | Helena
.
O que pensei foi simplesmente comparar a coluna row com a coluna id
retornando o primeiro registro que não coincidir os numeros,
que no exemplo acima retornaria 1, depois 2, depois 4...
.
ou seja, parece uma soluçao bem simples para o problema,
porém se alguém ver alguma falha, favor comentar,
segue o codigo abaixo:
No caso da tabela abaixo, que é resultado de uma query, temos a coluna "row"
que é o sequencial gerado pela query.
.
row | id | nome
-----------------
1 | 3 | Maria
2 | 5 | Beatriz
3 | 9 | Helena
.
O que pensei foi simplesmente comparar a coluna row com a coluna id
retornando o primeiro registro que não coincidir os numeros,
que no exemplo acima retornaria 1, depois 2, depois 4...
.
ou seja, parece uma soluçao bem simples para o problema,
porém se alguém ver alguma falha, favor comentar,
segue o codigo abaixo:
Select a.row from (SELECT row_number() OVER (PARTITION by 0) as row, campo_id as id FROM tabela) a where a.row <> a.id limit 1
GOSTEI 0
Alberto
11/05/2018
Corrigindo: faltou o order by no codigo anterior
Select a.row from (SELECT row_number() OVER (PARTITION by 0) as row, campo_id as id FROM tabela order by campo_id) a where a.row <> a.id limit 1
GOSTEI 0