Preencher Lacuna (GAP) em coluna de tabela PostgreSQL

PostgreSQL

11/05/2018

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?
Alberto

Alberto

Curtidas 0

Melhor post

Jair N.

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

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.
GOSTEI 0
Alberto

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:

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

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
POSTAR