Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

naofuieu

Qual uma maneira não-gambiarrenta de resolver isso?

Recommended Posts

Olá, galera!!!

 

Olha, eu tô com um problema sério pra resolver aqui. Eu tenho num banco de dados duas tabelas A e B tais que um atributo de B referencia um registro de A. O que eu tenho como problema é: eu tenho que inserir um registro em A e depois alguns em B, mas de forma que esses ultimos referenciem o que eu acabei de inserir.

O problema todo é que esse atributo referenciado é a chave primária da tabela A, que é auto-incrementável.

 

Eu não queria fazer aquela velha gambiarra de inserir, pegar o último registro inserido e recuperar os dados dele, a não ser que seja o jeito.

Queria saber se vocês não têm uma solução mais bonitinha e menos custosa... :D

 

Vou dar o esquema das tabelas abaixo:

Tabela ( A )

CREATE TABLE Questions (idQ INTEGER PRIMARY KEY AUTOINCREMENT, qText TEXT, numItems INT NOT NULL, numOpt INT NOT NULL, idGrade INT NOT NULL);

Tabela ( B )

CREATE TABLE Items (idItem INTEGER PRIMARY KEY AUTOINCREMENT, iText TEXT, idQ INT NOT NULL);

O atributo que referencia é o Items.idQ e o referenciado é o Questions.idQ

 

 

Valeeeuuu

Compartilhar este post


Link para o post
Compartilhar em outros sites

Se voce estiver usando um framework ORM como o hibernate voce pode utilizar o design pattern Observer.

 

Se estiver usando JDBC aconselho que acrescentes uma coluna do tipo datetime ou long na tabela A. Assim, no momento que voce der um insert na tabela A insira o valor referente ao momento da insercao. Quando for recuperar o ultimo valor inserido, consulte pela data.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Se voce estiver usando um framework ORM como o hibernate voce pode utilizar o design pattern Observer.

 

Se estiver usando JDBC aconselho que acrescentes uma coluna do tipo datetime ou long na tabela A. Assim, no momento que voce der um insert na tabela A insira o valor referente ao momento da insercao. Quando for recuperar o ultimo valor inserido, consulte pela data.

 

Não, não estou usando nenhum framework... A aplicação é simples e decidi utilizar JDBC mesmo.

Mas até que gostei dessa solução! Evita um bocado de processamento no banco... Mas será que não há uma forma melhor não...?

Se bem que agora fiquei seriamente inclinado a usar esse timestamp... heheheh :D

 

Valeu, Vergil

Compartilhar este post


Link para o post
Compartilhar em outros sites

O campo com o tempo / milisegundo da insercao deve aceitar valor nulo. O único risco desta solucao é o de dois usuários fazerem a facanha de inserir uma linha na tabela no mesmo milisegundo (o que e dificilimo, porem possivel). Mas para isso basta que voce sincronize o metodo que faz o insert. Assim uma thread espera a outra antes de fazer o insert.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom, esse timestamp resolve meu problema a contento, mas ainda não era o que eu queria, pois no banco vão ficar informações inúteis para a aplicação, no ponto de vista de que só vou precisar desse timestamp uma vez.

Além disso, do jeito que eu modelei o banco, eu vou ter que fazer isso também na outra tabela...

 

Vou explicar como funciona a coisa para que se alguém tiver uma ideia melhor de modelagem possa me ajudar.

 

A tabela Questions armazena as perguntas e a Items as opções de resposta das perguntas em Questions. Esse relacionamento é 1..*:0..*, ou seja, uma pergunta pode não ter nenhum ou vários itens e um item deve pertencer a pelo menos uma pergunta.

Desses itens, pelo menos um é considerado resposta correta, se existirem. Para isso, criei uma tabela que faz o relacionamento entre itens corretos e perguntas. Pensei em simplesmente colocar um atributo (correctAnsw) na tabela Items, mas fiquei bem em dúvida, pois sei que a maioria das perguntas a serem inseridas são de um único item correto, então esse atributo acabaria sendo espaço desperdiçado.

 

O ruim é que desse jeito eu vou ter que colocar timestamp também nos items, para poder saber quem qual o id dos itens que eu disse serem corretos...

 

Alguém? :D

 

Pra galera que quer saber um outro contorno a esse problema, eu consegui encontrar um meio que funciona dependendo da implementação do driver do banco de dados.

 

Existe uma assinatura do método executeUpdate da classe Statement que recebe uma flag (na verdade, não só nesse método como em todos os outros, acredito, que possam executar um INSERT). O link para a documentação é este.

 

Após usar esse método com a flag Statement.RETURN_GENERATED_KEYS, basta usar o método estático Statement.getGeneratedKeys(), que retorna um ResultSet com os valores gerados pelas inserções no campo AUTOINCREMENT, sem uma segunda consulta ao banco e, com isso, sem um overhead de gambiarra. Simples assim.

 

Apesar de ter resolvido o problema inicial, gostaria que mantivessem o tópico aberto para poder receber sugestões que eu pedi no post anterior.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pra galera que quer saber um outro contorno a esse problema, eu consegui encontrar um meio que funciona dependendo da implementação do driver do banco de dados.

 

Existe uma assinatura do método executeUpdate da classe Statement que recebe uma flag (na verdade, não só nesse método como em todos os outros, acredito, que possam executar um INSERT). O link para a documentação é este.

 

Após usar esse método com a flag Statement.RETURN_GENERATED_KEYS, basta usar o método estático Statement.getGeneratedKeys(), que retorna um ResultSet com os valores gerados pelas inserções no campo AUTOINCREMENT, sem uma segunda consulta ao banco e, com isso, sem um overhead de gambiarra. Simples assim.

 

Muito interessante! Desconhecia isso. Pra quem usa JDBC, essa é sem dúvida a solução correta.

Quanto ao campo pra armazenar o momento da inserção, ele tem uma outra utilidade. Controlar concorrência de acesso a dados por exemplo. O hibernate usa este recurso não só com o campo datetime, mas também com versionamento. Você pode por exemplo ter dois usuários atualizando a mesma linha da tabela de questões.

 

Quanto à dúvida sobre modelagem, eu acrescentaria um campo lógico (V ou F) na tabela de respotas. Seria um mísero byte por linha.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.