PostGree - Sequence com concatenção

18/11/2015

1

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 ?
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);   
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
×
+1 DevUP
Acesso diário, +1 DevUP
Parabéns, você está investindo na sua carreira