SEQUENCE POR EMPRESA

SINCLAIR 10/12/2014 00:40:01
#443097
Prezados,

PostGreSQL 9.3

Uso a criação de Sequences com bastante facilidade, até porque não há dificuldade no uso dos mesmos. é algo bem simples.

Até o momento tenho uma Sequence chamada ProximoCodCli que me fornece o próximo código para o cliente. E tudo funciona muito bem até que....

Mudando o sistema para Web (estou na fase de MER ainda) me chamou atenção para algo na frente. A tabela de clientes conterá CodigoDaEmpresa, CodigoDoCliente, Nome, CNPJCPF, etc...

Para a empresa de código 1 posso ter os clientes de de código 1 à n Mas se eu crio dois cliente na empresa 1 com códigos de cliente 1 e 2 (sequence), quando eu cadastrar um cliente na empresa 5 o código do cliente será 3 (sequence). Eu desejo deixar uma sequence para cada empresa, assim empresa 1 terá clientes e códigos de 1 a n e empresa 5 também com reinicio de sequence (código de 1 a n) e não pegando o último código utilizado na empresa 1.

Imaginei duas soluções:

Cada empresa teria seu banco de dados. Descartei porque a manutenção teria que ocorrer em cada banco de dados (quando houvesse manutenção). é menos trabalhoso e menos sujeito a erros fazer manutenção em um único banco de dados.

Para cada empresa teria uma sequence. Empresa 1 teria a sequence ProximoCodCli_1 e empresa 5 teria a sequence ProximoCodCli_5. Resolve, mas é bem uma solução intrínseca do PostGreSQL e sim uma solução baseada em código do sistema (que eu queria evitar, deixando o máximo possível de controle dentro do PostGreSQL e o sistema ser mais voltado para o front-end).

Algum dos colegas tem alguma idéia de como poderia ser contornado o problema sem usar as duas soluções que imaginei?

Tudo de bom.
NETMANIA 10/12/2014 08:02:25
#443099
Na minha opinião seria usar uma sequence para cada empresa, porem, quando a quantidade de empresas começar a crescer, você terá que gerenciar várias sequences diferentes,
TUNUSAT 10/12/2014 08:06:02
#443100
ZEUZEBIO3,

Eu faria uma tabela de Clientes com a chave composta. Uma parte da chave seria o código da Empresa como chave estrangeira (FK - Foreign Key) e a segunda parte é a própria chave primária (PK - Primary Key).
Por exemplo:

Empresa
CodEmpresa (PK)
Nome

Cliente
CodEmpresa (FK)
CodCliente (PK)


[][ô]s,
Tunusat.
MILENIO 10/12/2014 08:20:03
#443101
Seguindo a sugestão do colega Tunusat poderia fazer desta forma mantendo os dois números no mesmo campo da Tabela.

Exemplo:
Empresa 1
Cliente 1

imaginando que a chave de acesso seja numérica:
ChaveAcesso = (Empresa * 100000) + Cliente = 100001

Para não ter que digitar este código enorme na digitação pega Empresa e Cliente em Campos Separados.

Saudações



SINCLAIR 10/12/2014 10:42:53
#443110
Olá, Colegas...

A sugestão do colega Tunusat eu já utilizo, faz validação mas não impede de ficarem pulos na sequence, como narrei na abertura do post.

O colega NetMania sugere uma sequence para cada empresa, o que também na abertura do post eu havia dito ser uma das opções, mas que não deseja utilizar para que tudo fosse criado/mantido pelo próprio postgres e o sistema ficasse com sua finalidade inicial de ser o front-end apenas.

Acredito que a solução será uma mistura das opções: criar uma função que recebe o código da empresa e caso já exista sequence para a mesma, apenas retornará o próximo código na sequence. Caso não exista sequence para a empresa, criará a mesma e então retornará o código de cliente através da própria. Precisará ter padrão de nome da sequence, que imagino ser [Ô]seq_[Ô] seguido do código da empresa, seguido por [Ô]_codcli[Ô] (exemplo: seq_5_codcli para a sequence de clientes da empresa 5). Embora utilizando uma das duas alternativas que coloquei na abertura do post (e que não deseja utilizar), acredito que assim ficaria tudo dentro do postgres e, para chegar-se ao próximo código de cliente seria apenas um select na função passando o código da empresa como parâmetro, algo como Select ProximoCodigoCliente(5) para pegar o próximo código de cliente da empresa 5 (se [Ô]seq_5_codcli[Ô] não existir será criada).

Vou deixar o post ainda aberto por mais 1 dia, para que os colegas que desejarem manifestarem suas idéias e opniões.

Tudo de bom.
TUNUSAT 10/12/2014 12:28:18
#443111
ZEUZEBIO3,

Mas ... desculpe ... não entendi ... em que caso ficaria com [Ô]pulos na sequence[Ô]?
Por exemplo se você cadastrar:

1º) Caso:
Empresa - 1
Cliente - 1

2º) Caso:
Empresa - 2
Cliente - 1

São dois registros distintos, certo?
A chave seria composta (em campos separados):
1º) Caso a Chave ficará assim: [Ô]1 e 1[Ô];
1º) Caso a Chave ficará assim: [Ô]2 e 1[Ô];

Só ocorreriam [Ô]pulos[Ô] em caso de desistência de cadastramento. Vamos supor que duas pessoas estão cadastrando clientes para a Empresa [Ô]2[Ô].
Dai pegam duas chaves a saber:

3º) Caso:
Empresa - 2
Cliente - 2

4º) Caso:
Empresa - 2
Cliente - 3

Mas a primeira pessoa simplesmente desiste ou cai a energia e a chave [Ô]2 e 2[Ô] é perdida (caso 3º) ...
... bom ... o próximo número de chave seria [Ô]2 e 4[Ô]. Então a chave [Ô]2 e 2[Ô] ficaria sem uso ... seria este o problema?

*** Outra idéia:

- Criar uma tabela de [Ô]controle[Ô] que teria obrigatoriamente todas as PKs das empresas cadastradas em forma de registros. Uma vez criada a empresa é obrigatório criar um registro para ela nesta tabela. E nesta tabela um dos campos seria um [Ô]sequence[Ô] que armazenaria o último número utilizado pelo cliente. Mas ele só pode ser atualizado quando for confirmado a criação do registro de novo cliente. Isto complicaria a manutenção, porém você pode colocar para cada empresa outros campos de controle personalizando o tratamento de cada empresa. Ficaria assim, por exemplo:

Tabela de controle [Ô]tblControlEmpresa[Ô].
Campos:
- IdEmpresa;
- SequenceCliente;
- OutroControleQualquerParaEstaEmpresa;

[][ô]s,
Tunusat.
SINCLAIR 10/12/2014 15:12:00
#443116
Oi, Tunusat...

Mais uma vez grato pela resposta.

No caso de

Citação:

- Criar uma tabela de [Ô]controle[Ô] que teria obrigatoriamente todas as PKs das empresas cadastradas em forma de registros. Uma vez criada a empresa é obrigatório criar um registro para ela nesta tabela. E nesta tabela um dos campos seria um [Ô]sequence[Ô] que armazenaria o último número utilizado pelo cliente. Mas ele só pode ser atualizado quando for confirmado a criação do registro de novo cliente. Isto complicaria a manutenção, porém você pode colocar para cada empresa outros campos de controle personalizando o tratamento de cada empresa. Ficaria assim, por exemplo:



Também foi uma das minhas primeiras tentativas, mas além do controle desta tabela em inserções de dados, considerei que para buscar o código, logo antes do insert dos clientes, bastaria

Select max(codcli) + 1as PrxCodCli from TabClientes Where CodEmp=5

Substutuindo o 5 pelo código da empresa. O código do próximo cliente seria o PrxCodCli da Query anterior. Só não apliquei por seria via código e eu gostaria de deixar tudo dentro do PostGreSQL. Pensei em triggers, functions... mas que ficasse dentro do PostGreSQL.

No outro caso, este que você indicou...

Citação:

1º) Caso:
Empresa - 1
Cliente - 1

2º) Caso:
Empresa - 2
Cliente - 1

São dois registros distintos, certo?
A chave seria composta (em campos separados):
1º) Caso a Chave ficará assim: [Ô]1 e 1[Ô];
1º) Caso a Chave ficará assim: [Ô]2 e 1[Ô];

Só ocorreriam [Ô]pulos[Ô] em caso de desistência de cadastramento. Vamos supor que duas pessoas estão cadastrando clientes para a Empresa [Ô]2[Ô].
Dai pegam duas chaves a saber:

3º) Caso:
Empresa - 2
Cliente - 2

4º) Caso:
Empresa - 2
Cliente - 3



Eu já havia tentado. Por algum motivo não funcionou. Empresa 1 ficou com cliente 1. Empresa 1 (novamente) ficou com cliente 2 (até aqui tudo certo)... mas a empresa 2 não ficou com cliente 1 (ficou cliente 3). Olhei e [Ô]re-olhei[Ô] a estrutura do BD e esta certo, tanto a PK quanto FK. Dai resolvi fazer o post. Mas vou tentar novamente, considerando que nas vezes que eu tenha feito eu tenha cometido algum erro básico que não percebi (justamente por ser muito básico pode ser que passe despercebido). Mas vou tentar novamente e posto o resultado.

Grato!
SINCLAIR 11/12/2014 11:15:35
#443133
Prezados,

Para não ficar o post aberto, vou encerrá-lo. Acho que a melhor saída será mesmo criar uma função que conforme necessário usa ou cria uma sequence para a empresa.

Grato a todos que responderam.

Tudo de bom.
Tópico encerrado , respostas não são mais permitidas