PostGree - Sequence com concatenção

18/11/2015

0

Pessoal, estou precisando criar um campo, onde ele terá que receber um certo valor mais o sequencial....sendo que pensei da seguinte maneira:

Crio um campo chamado idsequencial tipo serial
Crio um outro campo chamado serie
Outro campo chamado novonumero int

então crio um trigger, para pegar o idsequencial e o serie, para casar os dois e gerar o novonumero, por exemplo:



idsequencia = 7762
serie = 3

o novonumero seria serie mais idsequencia = 37762




Tenho como fazer algo mais automatico ?

Vou resumir e explicar....

Temos 14 lojas....cada loja tem sua tabela de venda sendo loja, coo e ecf como controles....

agora preciso, pegar as vendas de todas as lojas e incluir em uma tabela que seu controle seja loja e ticket, o bendito do ticket é char(8) "Sem comentários, aqui, não fui eu que fiz a merda e prefiro ficar quieto"

Então, para não dar problema de uniquekey do loja e ticket já que na loja o coo pode repetir, mas coo e ecf não!

pensei fazer o que falei acima....

Sigo isso ou tenho algo melhor ?
Robson Morais

Robson Morais

Responder

Post mais votado

19/11/2015

Consegui resolver....vou deixar aqui o script para quem precisar....




    
     
/*DROPA TUDO CASO QUEIRA LIMPAR E INICIAR DO ZERO*/     
DROP TRIGGER t_gerasequence ON testesequence;
DROP FUNCTION f_gerasequence();
drop table seriesequence;
drop table testesequence; 
DROP SEQUENCE idsequencial;
drop SEQUENCE seqserie;
 

/*TABELA DE CONTROLE DE SERIE*/
create table seriesequence(
serie INT
,dt_cadastro timestamp default current_timestamp
)

/*SEQUENCE DA TABELA DE SEQUENCIA*/     
CREATE SEQUENCE seqserie
 INCREMENT 1
 MINVALUE 0
 MAXVALUE 99
 CACHE 1;

/*ADICIONA O SEQUENCE IDSEQUENCIAL NA TABELA TESTESEQUENCE NO CAMPO IDSEQUENCIA*/
ALTER TABLE seriesequence ALTER COLUMN serie SET DEFAULT NEXTVAL('seqserie'::regclass);


/*TABELA DE TESTE DE SEQUENCIA*/
create table testesequence(
     cd_empresa int
     ,coo int
     ,idcaixa int
     ,idsequencial int
     ,serie int)

/*SEQUENCE DA TABELA DE SEQUENCIA*/     
CREATE SEQUENCE idsequencial
 INCREMENT 1
 MINVALUE 0
 MAXVALUE 100
 CACHE 1;

/*ADICIONA O SEQUENCE IDSEQUENCIAL NA TABELA TESTESEQUENCE NO CAMPO IDSEQUENCIA*/
ALTER TABLE testesequence ALTER COLUMN idsequencial SET DEFAULT NEXTVAL('idsequencial'::regclass);

/*ADICIONA O SEQUENCE IDSEQUENCIAL NA TABELA TESTESEQUENCE NO CAMPO IDSEQUENCIA*/
--COM ISSO AO INCLUIR O REGISTRO NA TABELA testesequence ELE IRA PEGAR A SERIE ATUAL
ALTER TABLE testesequence ALTER COLUMN serie SET DEFAULT currval('seqserie'::regclass);


/*CRIA A FUNCTION TRIGGER PARA RESTARTAR A SEQUENCE E CRIAR UMA NOVA SERIE*/     
CREATE OR REPLACE FUNCTION f_gerasequence()
  RETURNS trigger AS
$BODY$
DECLARE
    vSeq  int; 
    vSerie  int;
BEGIN	
	--RETORNA O IDSEQUENCIAL ATUAL
	vSeq := currval('idsequencial');
	--VERIFICA SE A SEQUENCIA ATINGIU O TANTO QUE VOCE QUEIRA
	if vSeq >= 5 then
	--INSERE UMA NOVA SEQUENCIA
      INSERT INTO seriesequence (dt_cadastro) values (current_timestamp);
     --REINICIA A SEQUENCE IDSEQUENCIAL 
      ALTER SEQUENCE idsequencial RESTART WITH 1;
      --PEGA O NUMERO DE SERIE
      vSerie := currval('seqserie');
      
   end if;
    RETURN new;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100; 

  
 /*TRIGGER PARA EXECUTAR A FUNCTION TRIGGER f_gerasequence ANTES DE INSERIR*/  
CREATE TRIGGER t_gerasequence
  BEFORE INSERT
  ON testesequence
  FOR EACH ROW
  EXECUTE PROCEDURE f_gerasequence();

    
SELECT setval('idsequencial', 0);

SELECT setval('seqserie', 1);

--delete from seriesequence;
--DELETE from testesequence;
     
     
     insert into testesequence (cd_empresa,coo,idcaixa) values (2,1235,23);
     insert into testesequence (cd_empresa,coo,idcaixa) values (3,1235,23);     
     insert into testesequence (cd_empresa,coo,idcaixa) values (4,1235,23);     
     insert into testesequence (cd_empresa,coo,idcaixa) values (5,1235,23);     
     insert into testesequence (cd_empresa,coo,idcaixa) values (6,1235,23);     
     insert into testesequence (cd_empresa,coo,idcaixa) values (7,1235,23);     
     insert into testesequence (cd_empresa,coo,idcaixa) values (8,1235,23);     
     insert into testesequence (cd_empresa,coo,idcaixa) values (9,1235,23);   
          
     insert into testesequence (cd_empresa,coo,idcaixa) values (2,13235,23);
     insert into testesequence (cd_empresa,coo,idcaixa) values (3,12435,23);     
     insert into testesequence (cd_empresa,coo,idcaixa) values (4,12535,23);     
     insert into testesequence (cd_empresa,coo,idcaixa) values (5,12315,23);     
     insert into testesequence (cd_empresa,coo,idcaixa) values (6,12352,23);     
     insert into testesequence (cd_empresa,coo,idcaixa) values (7,12345,23);     
     insert into testesequence (cd_empresa,coo,idcaixa) values (8,12356,23);     
     insert into testesequence (cd_empresa,coo,idcaixa) values (9,12357,23);   

Robson Morais

Robson Morais
Responder

Mais Posts

18/11/2015

Robson Morais

Alguém ?
Responder

18/11/2015

Marcos P

A princípio é isso mesmo... contudo, se você vai fazer o controle pelo campo concatenado, qual a dificuldade em fazer em dois campos separados ?

Ou seja, concatenar em tempo de execução do lado da aplicação...

Não acaba dando no mesmo ?
Responder

18/11/2015

Robson Morais

Na aplicação é algo que não podemos mexer agora e também há muitas mudanças depois.....então acho que deixar o banco trabalhar...até mesmo porque são 30 caixas por loja...ai só no banco.
Responder

18/11/2015

Marcos P

A questão é que fazer isso via Trigger pode ( em algum momento ) começar a incomodar...
Responder

18/11/2015

Robson Morais

será ?

Hoje tenho uma function para gerar faturas de cartão de crédito e o trigger que chama essa function quando há um insert ou um update, não vi dar problema até agora e olha que a porrada de dados é muito grande
Responder

18/11/2015

Marcos P

Você não tem alternativa... senão pode ajustar na aplicação, só via Trigger mesmo !
Responder

18/11/2015

Robson Morais

Só queria saber se com o sequence ele dar para criar....tipo chegou em 999.999 gerar 02 e inicia 000.001
Responder

18/11/2015

Marcos P

Você pode reiniciar o Sequence desde que o campo não seja PK na tabela.

Contudo o processo deve ser manual, assim como mudar a série de controle para "02"...
Responder

18/11/2015

Robson Morais

então trigger mesmo....rs

Obrigado.
Responder

19/11/2015

Robson Morais

como reinicio uma sequence pela function....estou fazendo assim:

     
CREATE OR REPLACE FUNCTION f_gerasequence()
  RETURNS trigger AS
$BODY$
DECLARE
    vSeq  int;   
    vSerie  int; 
BEGIN	
	SELECT idsequencial into vSeq from testesequence where cd_empresa = NEW.CD_EMPRESA and coo = NEW.COO and idcaixa = NEW.IDCAIXA; 
	SELECT max(serie) into vSerie from seriesequence;
	if vSeq <= 5 then
	  update testesequence set serie = vSerie where cd_empresa = NEW.CD_EMPRESA and coo = NEW.COO and idcaixa = NEW.IDCAIXA;  
    else
      vSerie := vSerie+1;
      INSERT INTO seriesequence (serie) values (vSerie);
      
      SELECT setval('idsequencial', 1);       
      
      update testesequence set serie = vSerie where cd_empresa = NEW.CD_EMPRESA and coo = NEW.COO and idcaixa = NEW.IDCAIXA;
    end if;
    RETURN NEW;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100; 


mas no trecho de setar novamente a sequece dá erro, há não sei que faço manual o mesmo comando.
Responder

Que tal ter acesso a um e-book gratuito que vai te ajudar muito nesse momento decisivo?

Ver ebook

Recomendado pra quem ainda não iniciou o estudos.

Eu quero
Ver ebook

Recomendado para quem está passando por dificuldades nessa etapa inicial

Eu quero

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

Aceitar