Lançado Adianti Framework 7.6!
Clique aqui para saber mais
Chave primária composta Existe algum meio de utilizar chave primaria composta tipo estou tentando migrar um aplicativo que tenho escrito em lazarus que tem a seguinte situacao cod_empresa integer, cod_ordempagamento, esses dois campos precisam fazer parte da chave primaria pois a numeracao de cada empresa precisa ser individual...
FP
Chave primária composta  
Fechado
Existe algum meio de utilizar chave primaria composta tipo estou tentando migrar um aplicativo que tenho escrito em lazarus que tem a seguinte situacao
cod_empresa integer,
cod_ordempagamento,
esses dois campos precisam fazer parte da chave primaria pois a numeracao de cada empresa precisa ser individual

Pacotão Dominando o Adianti Framework 7
O material mais completo de treinamento do Framework.
Curso em vídeo aulas + Livro completo + Códigos fontes do projeto ERPHouse.
Conteúdo Atualizado! Versão 7.4


Dominando o Adianti 7 Quero me inscrever agora!

Comentários (11)


PD

Oi Fernando,

Vou colar o que respondi pelo grupo do face:

Pablo: Um padrão de projeto muito usado em Framework é o Identity Field, ou seja, cada objeto deve ter um identificador único, correspondente à uma chave primária surrogate, ou seja, sem sentido algum no mundo real. Sua antiga chave primária composta se transformará em duas chaves estrangeiras simples. Para evitar que sejam inseridos valores duplicados no banco de dados, crie um índice único (Unique Index) composto pelas duas chaves estrangeiras e deixe o banco de dados evitar a duplicidade. Era isso, simples assim :-)

Fernando: então muito obrigado Pablo, porem fica a duvida minha chave composta poderia ser tratada no Adianti?

Pablo: Não sem alguma gambiarra. Sendo gambiarra foge dos padrões e acaba trazendo problemas indiretos. Logo recomendo descartar. Apesar do nome ser parecido, não confundam chave composta composição São coisas totalmente diferentes. Abraço!
CG

Boa tarde pessoal,

Apenas complementando o forum.

No sistema que estou desenvolvendo uso o patern "surrogate key".

Contudo, existem situações que, para garantir a integridade dos dados, torna-se necessário existir uma "chave composta".

Neste casos, crio uma UNIQUE KEY no banco com os campos que considero a "chave composta" da tabela.

Quando tiver um tempo, vou postar um artigo neste site ensinando como que se faz.

FP

Muito obrigado pelas reposta e fico aguardando seu artigo Carlos Fabiano Gonsalves acredito que ja entendi a situacao porem nao custa nada ver mais uma artigo a respeito kkkk
JA

Olá, estou usando o framework para fazer algumas operações numa base de dados já preenchida com dados. Não vou fazer inclusões nesta base de dados, apenas vou carregar os registros em objetos TRecord para consultas. Acontece que a tabela que estou trabalhando possui uma chave primária composta e o banco de dados já garante a unicidade dos registros.


Qual a melhor forma de fazer o carregamento dos registro usando o framework Adianti e ao mesmo tempo sem fazer muita gambiarra? : )

Estava pensando em apenas reescrever o método load() na nova classe filha de TRecord.
CG

Prezado Jairo bom dia,

Pelo que entendi, você quer recuperar as informações do banco de dados e utilizará temporariamente, certo?

Você não precisa fazer gambiarra, pois o framework permite que você recupere as informações da maneira que você quer, utilizando o método load sem sobrescrevê-lo.

Basta colocar utilizar classe TCriteria para filtrar as informações da maneira que você precisa.

Dá uma olhada nos exemplos do site para você fazer. Se é novato no framework, sugiro comprar o livro do Pablo, pois vai lhe ajudar bastante!!!

Outra coisa....

Dá uma lida na resposta do Pablo acima acerca de chaves compostas, pois existem maneira melhores de trabalhar com chaves compostas, utilizando o Adianti.
JA

Eu já usei o framework (na verdade eram as classes criadas no livro PHP com Orientações a Objetos).
Eu queria criar um modelo de classes para uma base de dados já existente. Acontece que essa base de dados é de um outro sistema e com chave primária composta.

Como você sugere utilizar a classe TCriteria? Porque eu não gostaria de utilizar as classes isoladamente. Por exemplo, TTransaction e TConnection para fazer a conexão, TSelect e TCriteria para fazer as consultas na base. Pretendia criar uma classe que representaria um determinada tabela dessa base de dados e realizar, a princípio, consultas nela.

Porém, uma classe TRecord só pode ter um campo como chave primária. Por isso pensei em reescrever o método load() nessa classe filha de TRecord colocando mais de um campo no critério de busca.


Pelo que entendi na resposta do Pablo eu terei de criar um outro campo na tabela da base de dados para ser uma chave primária (surrogate) e as chaves primárias originais servirão como chaves estrangeiras, correto?

Obrigado, pela ajuda!
CF

Prezado Jairo Boa tarde,

Segue aqui um exemplo para recuperar os dados de uma tabela, que possui chame composta:


  1. <?php
  2.    $repository = new TRepository('ItemNotaFiscal');
  3.    $criteria = new TCriteria;
  4.    $criteria->add(new TFilter(new TFilter('notafiscal_id''='10);
  5.    $criteria->add(new TFilter(new TFilter('itemnotafiscal_id''='1);
  6.    $itens $repository->load($criteria);
  7.   foreach($itens as $item){
  8.        print_r($item);
  9.   }
  10. ?>


Desta maneira você recuperará os registros utilizando a chave composta da sua tabela.

Espero ter ajudado.

JA

Obrigado pela ajuda. No momento não estou mais trabalhando com isso, mas eu entendi a ideia. Esta mesma ideia poderia ser utilizada para um comando de update, por exemplo. Atualiza o registro que corresponde ao critério da chave composta.
GC

Pessoal, esse post é bem antigo mas achei pertinente dar sequencia aqui...

Imagine hipoteticamente um sistema multiempresa e multifilial com as tabelas abaixo:

EMPRESA
id pk
nome_empesa

FILIAL
id pkj
empresa_id fk empresa(id)
nome_filial

Considerando o caso acima, tenho com facilidade uma empresa e muitas filiais, mas quando acrescento uma nova empresa o id da filial se mantém em sequencia evidentemente, qdo na pratica deveria retornar a 1...

FILIAL
id empresa_id
1 1
2 1
3 2

O Carlos acima deu uma solução que seria concatenar os campos id + empresa_id num único campo que se tornaria a chave primaria da tabela, é claro que eu poderia tratar utilizando uma chave primaria composta, mas estou considerando o uso do Framework, alguém tem uma ideia diferente, um padrão de projeto, ou algo do tipo?

Desde já agradeço.

PD

Geraldo,

Não penso que o id da filial deva retornar à 1. ID é uma informação interna somente para vincular o registro ao banco de dados. Ele não deve ser utilizado para representar sequências, quantidades. Para tal, você pode criar um outro atributo "legível" ao usuário.

Att,
HJ

Pessoal, mesmo alterando a minha tabela, usando Unique index ao invés de constraint, o erro que eu estava encontrando permaneceu o mesmo.

Criação da tabela:
CREATE TABLE fifin (
conta varchar(20),
competencia date,
valor float(10,2),
qtde float(10,2),
coef float(10,5),
rotina varchar(10) NOT NULL,
dt_pagto date,
colab_id BIGINT UNSIGNED NOT NULL,
FOREIGN KEY(conta) REFERENCES conts(conta),
FOREIGN KEY(colab_id) REFERENCES colab(id),
FOREIGN KEY(rotina) REFERENCES rotin(codigo),
UNIQUE KEY chave (colab_id,competencia,dt_pagto,rotina,conta)) ENGINE=INNODB;

FifinList.class.php
...
// creates the datagrid columns
$column_check = new TDataGridColumn('check', '', 'center');
$column_conta = new TDataGridColumn('conta', 'Conta', 'left');
$column_conta_desc = new TDataGridColumn('descricao', 'Descricao', 'left');
$column_valor = new TDataGridColumn('valor', 'Valor', 'right');
$column_qtde = new TDataGridColumn('qtde', 'Quantidade', 'right');
$column_coef = new TDataGridColumn('coef', 'Coeficiente', 'right');
$column_rotina = new TDataGridColumn('rotina', 'Rotina', 'left');
$column_dt_pagto = new TDataGridColumn('dt_pagto', 'Data Pagto', 'center');

$column_valor->setTransformer(array($this, 'formatContas'));

// add the columns to the DataGrid
$this->datagrid->addColumn($column_check);
$this->datagrid->addColumn($column_conta);
$this->datagrid->addColumn($column_valor);
$this->datagrid->addColumn($column_qtde);
$this->datagrid->addColumn($column_coef);
$this->datagrid->addColumn($column_rotina);
$this->datagrid->addColumn($column_dt_pagto);
...

Mensagem de erro ao carregar Fifinlist.class.php('You have already added a field called "checkSALARIO" inside the form')

Onde estou errando?