PostGree - Sequence com concatenção
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 ?
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
Curtidas 0
Melhor post
Robson Morais
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);
GOSTEI 1
Mais Respostas
Robson Morais
18/11/2015
Alguém ?
GOSTEI 0
Marcos P
18/11/2015
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 ?
Ou seja, concatenar em tempo de execução do lado da aplicação...
Não acaba dando no mesmo ?
GOSTEI 0
Robson Morais
18/11/2015
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.
GOSTEI 0
Marcos P
18/11/2015
A questão é que fazer isso via Trigger pode ( em algum momento ) começar a incomodar...
GOSTEI 0
Robson Morais
18/11/2015
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
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
GOSTEI 0
Marcos P
18/11/2015
Você não tem alternativa... senão pode ajustar na aplicação, só via Trigger mesmo !
GOSTEI 0
Robson Morais
18/11/2015
Só queria saber se com o sequence ele dar para criar....tipo chegou em 999.999 gerar 02 e inicia 000.001
GOSTEI 0
Marcos P
18/11/2015
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"...
Contudo o processo deve ser manual, assim como mudar a série de controle para "02"...
GOSTEI 0
Robson Morais
18/11/2015
então trigger mesmo....rs
Obrigado.
Obrigado.
GOSTEI 0
Robson Morais
18/11/2015
como reinicio uma sequence pela function....estou fazendo assim:
mas no trecho de setar novamente a sequece dá erro, há não sei que faço manual o mesmo comando.
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.
GOSTEI 0