Preencher Lacuna (GAP) em coluna de tabela PostgreSQL

11/05/2018

0

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

Responder

Post mais votado

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

Jair N.

Jair N.
Responder

Mais Posts

11/05/2018

Alberto

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.
Responder

13/05/2018

Alberto

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



Responder

13/05/2018

Alberto

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
Responder

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

Aceitar