SQLs diferentes [RESOLVIDO]

14 respostas
J

Olá,
Tenho um método que faz um insert automático, passando apenas um objeto.
Mas surgiu um problema, exemplo:

eu uso MySQL, quando a coluna que for PK for um autoincremento, eu não preciso me preocupar em passar o valor,
porém, se eu mudar o banco para Oracle, ele não vai funcionar, pois precisa da sequence.nextval para funcionar o autoincremento do Oracle,
desse modo, como pode ser feito para ficar o mais genérico possível ? senão o método vai funcionar apenas para MySQL.

Obrigado.

14 Respostas

Nicolas_Fernandes

joaoo:
Olá,
Tenho um método que faz um insert automático, passando apenas um objeto.
Mas surgiu um problema, exemplo:

eu uso MySQL, quando a coluna que for PK for um autoincremento, eu não preciso me preocupar em passar o valor,
porém, se eu mudar o banco para Oracle, ele não vai funcionar, pois precisa da sequence.nextval para funcionar o autoincremento do Oracle,
desse modo, como pode ser feito para ficar o mais genérico possível ? senão o método vai funcionar apenas para MySQL.

Obrigado.

  1. Porque não testar o Hibernate ao invés de criar classes DAO na mão?
  2. Porque não faz o seu MySQL ir incrementando a chave através de uma sequence ou seja lá o que ele usa para esse tipo de controle?
  3. Ou então você pode adicionar o ID no objeto através da instrução “Select Max(ID) From Table”, que serve para todos, e boa!
public void adicionarRegistro(Objeto objeto, Connection conn) throws Exception
{
   objeto.setID(buscarIDMaximo(conn));
   String query = "Insert Into Tabela blablablabla";
   //...
}

public int buscarIDMaximo(Connection conn) throws Exception
{
   String query = "Select Max(ID) From Tabela";
   //...
   return idMaximo;
}

Algo assim, funcionaria nos dois!
Abraços!

nel

Como não vai funcionar?
Independente do banco que utiliza, na minha humilde opinião, este tipo de situação deve ser tratada pelo SGBD e não em código.
Quando você cria uma tabela em MySQL você informa qual campo terá autoincremente e no Oracle você simplesmente cria uma sequence, ou seja, o seu código permanece o mesmo o que muda é a configuração e/ou criação de suas tabelas.

Abraços.

nel

Nicolas Fernandes:
joaoo:
Olá,
Tenho um método que faz um insert automático, passando apenas um objeto.
Mas surgiu um problema, exemplo:

eu uso MySQL, quando a coluna que for PK for um autoincremento, eu não preciso me preocupar em passar o valor,
porém, se eu mudar o banco para Oracle, ele não vai funcionar, pois precisa da sequence.nextval para funcionar o autoincremento do Oracle,
desse modo, como pode ser feito para ficar o mais genérico possível ? senão o método vai funcionar apenas para MySQL.

Obrigado.

  1. Porque não testar o Hibernate ao invés de criar classes DAO na mão?
  2. Porque não faz o seu MySQL ir incrementando a chave através de uma sequence ou seja lá o que ele usa para esse tipo de controle?
  3. Ou então você pode adicionar o ID no objeto através da instrução “Select Max(ID) From Table”, que serve para todos, e boa!
public void adicionarRegistro(Objeto objeto, Connection conn) throws Exception
{
   objeto.setID(buscarIDMaximo(conn));
   String query = "Insert Into Tabela blablablabla";
   //...
}

public int buscarIDMaximo(Connection conn) throws Exception
{
   String query = "Select Max(ID) From Tabela";
   //...
   return idMaximo;
}

Algo assim, funcionaria nos dois!
Abraços!

Não é por nada, mas sinto que isso pode gerar uma exceção de violação de integridade.
Imagina a situação de duas threads acessarem ao mesmo tempo a mesma tabela, é um exemplo que provavelmente viria a gerar problema.

Como eu citei, o recomendavél é deixar isto a cargo do SGBD.

Abraços.

Nicolas_Fernandes

nel:
Nicolas Fernandes:
joaoo:
Olá,
Tenho um método que faz um insert automático, passando apenas um objeto.
Mas surgiu um problema, exemplo:

eu uso MySQL, quando a coluna que for PK for um autoincremento, eu não preciso me preocupar em passar o valor,
porém, se eu mudar o banco para Oracle, ele não vai funcionar, pois precisa da sequence.nextval para funcionar o autoincremento do Oracle,
desse modo, como pode ser feito para ficar o mais genérico possível ? senão o método vai funcionar apenas para MySQL.

Obrigado.

  1. Porque não testar o Hibernate ao invés de criar classes DAO na mão?
  2. Porque não faz o seu MySQL ir incrementando a chave através de uma sequence ou seja lá o que ele usa para esse tipo de controle?
  3. Ou então você pode adicionar o ID no objeto através da instrução “Select Max(ID) From Table”, que serve para todos, e boa!
public void adicionarRegistro(Objeto objeto, Connection conn) throws Exception
{
   objeto.setID(buscarIDMaximo(conn));
   String query = "Insert Into Tabela blablablabla";
   //...
}

public int buscarIDMaximo(Connection conn) throws Exception
{
   String query = "Select Max(ID) From Tabela";
   //...
   return idMaximo;
}

Algo assim, funcionaria nos dois!
Abraços!

Não é por nada, mas sinto que isso pode gerar uma exceção de violação de integridade.
Imagina a situação de duas threads acessarem ao mesmo tempo a mesma tabela, é um exemplo que provavelmente viria a gerar problema.

Como eu citei, o recomendavél é deixar isto a cargo do SGBD.

Abraços.

Olhando por esse ponto, realmente concordo contigo. Pode gerar uma violação de integridade, onde duas threads pegam o mesmo valor ao mesmo tempo.

No MySQL, é possível implementar uma Sequence como no Oracle?

nel

Então, na realidade quando você define uma tabela no MySQL você adiciona o seguinte comentário, exemplo:

CREATE TABLE id not nul AUTO_INCREMENT;

Desta forma, sempre que você inserir algo na tabela, ele gera automaticamente um novo valor para o campo id, assim como a sequence faz no Oracle.
Assim, basta definir a sua PK como AUTO_INCREMENT que dificilmente você terá problemas com violação de integridade.

Aqui tem um manual bem bacana de MySQL.
Abraços.

J

Olá,
Obrigado a todas as respostas, mas continuando…

  1. Pois então, não quero utilizar nenhum framework para desenvolvimento no momento, ou seja o hibernate está fora de cogitação.
  2. Sintaxe de MySQL para um insert:
    insert into disciplina (descricao,professor) values (‘matematica’,‘fulano’)
    isso considerando que a chave primária está com um auto incremento.
    funciona perfeitamente.

Sintaxe de Oracle para um insert:
insert into disciplina values (seq_disc.nextval,‘matematica’,‘fulano’)
isso considerando que foi criado um sequence (seq_disc) no banco.

ou seja, se no meu método genérico tiver pra mysql e eu eestiver usando mysql, ok, mas se depois eu trocar pra Oracle, não funcionará mais.

Nicolas_Fernandes

nel:
Então, na realidade quando você define uma tabela no MySQL você adiciona o seguinte comentário, exemplo:

CREATE TABLE id not nul AUTO_INCREMENT;

Desta forma, sempre que você inserir algo na tabela, ele gera automaticamente um novo valor para o campo id, assim como a sequence faz no Oracle.
Assim, basta definir a sua PK como AUTO_INCREMENT que dificilmente você terá problemas com violação de integridade.

Aqui tem um manual bem bacana de MySQL.
Abraços.

Isso eu sei. Eu quis dizer se dá para fazer uma Sequence também no MySQL, como no Oracle.
E, se tiver como, respondo a questão do nosso amigo joaoo!

A

uma dúvida: pq está evitando frameworks?
se for para recriar toda a funcionalidade que um framework existente fornece, deveria reconsiderar essa sua opção…

de qualquer forma, a estratégia de geração de ids é diferente para os dois bancos… no oracle não tem auto-incremento…

a sequence é usada para este objetivo, mas são coisas diferentes…

você pode tornar sua classe que gera inserts automáticos configurável: como ela gera essa columa id…
daí você pode trabalhar com várias opções: auto-incremento, sequence, tabela de controle, etc
(essa configuração é basicamente o que o hibernate faz)

J

obrigado a todos de novo,

No MySQL existe o auto_increment, que é específico para uma coluna, já é setado no momento da criação da tabela, diferente do sequence do Oracle
que eu posso usar para qualquer tabela.
E pelo que li só encontrei esse auto increment como sequência no MySQL.

J

O fato de eu não querer utilizar frameworks é por puro estudo mesmo. Pois por mais que eles facilitem a questão eu quero ver como realmente acontece o que acontece.

Bom, mas se eu for fazer cada verificação para os inserts, e demais códigos SQLs para ficar algo em que possa ser usado para diversos banco de dados…
eu acho estranho desse jeito, pois por mais que digam que o java suporta diversos banco de dados (não estou negando isso), para o desenvolvedor posteriormente migrar para outro banco de dados, deverá alterar linhas de código DML.

Obrigado.

nel

João, você já testou isso no Oracle?
Pelo o que eu sei, não se faz necessário informar no ResultSet a sequence do Oracle, basta fazer como faria no MySQL.

Abraços.

Edit: desconheço criação de sequence no MySQL seguindo o mesmo formato do Oracle, pode haver outras alternativas para substituir o AUTO_INCREMENT diretamente no SGBD, mas para este caso, desconheço a solução.

J

Então Nel,
testei sim cara, e se eu não especificar, ele dá um erro dizendo que não pode receber null.
até onde eu sei, o sequence não se aplica especificamente a uma coluna, desse modo ele se perde.

nel

AbelBueno:
uma dúvida: pq está evitando frameworks?
se for para recriar toda a funcionalidade que um framework existente fornece, deveria reconsiderar essa sua opção…

de qualquer forma, a estratégia de geração de ids é diferente para os dois bancos… no oracle não tem auto-incremento…

a sequence é usada para este objetivo, mas são coisas diferentes…

você pode tornar sua classe que gera inserts automáticos configurável: como ela gera essa columa id…
daí você pode trabalhar com várias opções: auto-incremento, sequence, tabela de controle, etc
(essa configuração é basicamente o que o hibernate faz)

Bom, se eu souber de outra forma lhe aviso, estou tão acostumado com JPA que fazer inserts entre outros via JDBC fica estranho até!
Mas siga a dica do Abel, faça um DAO generico e em particular, os métodos INSERT. Desta forma, como ele mesmo citou, você deixa o seu sistema “independente de SGBD”, no que diz respeito aos INSERT.

Abraços.

J

É, eu estava tentando evitar esse tipo de situação, mas acho que vou ter que fazer uma verificação de banco mesmo.
Bom, obrigadão pela ajuda.
:smiley:

Criado 11 de setembro de 2010
Ultima resposta 11 de set. de 2010
Respostas 14
Participantes 4