Não sei se alguém aqui tem alguma carta na manga pra esse tipo de coisa. Mas eu sempre fiz “na mão” mesmo esse tipo de coisa, e não vejo outro modo de fazer.
String tabela = "usuarios";
String sql = "SELECT * FROM "+ tabela +" WHERE status= ?";
Até pela própria natureza de bind variables, que são usadas para que o banco de dados mantenha um plano de acesso para consultas iguais com parametros diferentes.
É impossível (pelo menos no meu entendimento da coisa) bindar o nome de uma tabela.
São parâmetros q vem direto da linha de comando. Preciso deixar isso bem protegido. O usuário vai passar os parâmetros e os resultados serão armazenados em arquivos.
Qd tento isso direto, ele acusa erro:
Syntax error or access violation message from server: "You have an error in your SQL syntax.
Check the manual that corresponds to your MySQL server
version for the right syntax to use near ''eta20' WHERE forecast='2005-06-20 00:00:00' ORDER BY idStation"
Quem vai reclamar não é driver JDBC, até pq ele não tem inteligência pra dizer se a query tá certa ou errada. Quem vai reclamar é o banco de dados mesmo, dizendo que não pode bindar (alguém tem uma tradução melhor pra isso?) a variável.
No Oracle eu sei que não funciona. Pode ser que em outros SGDBs, que não usem bind variables, funcione. Enfim… :mrgreen:
Ah é, quando ele vê que o objeto é um string ele dá um setString e faz o escape do String. Bem que o ZehOliveira falou :mrgreen:
Mas se você souber o nome de todas as tabelas que são assim, ou pelo menos tiver como saber o nome de todas elas quando a aplicação iniciar, inicializa todos os prepared statements e mantém um Map ou uma collection qualquer com eles, assim quando você precisar, é só ir lá no map e pegar denovo
Acho que o MySQL se encaixa no exemplo de SGDBs que eu citei acima.
Quando você faz: setString(1, "tabela");
Ao invés de ser gerado: “SELECT *FROM tabela …”
Ele gera: “SELECT * FROM ‘tabela’ …”
(Veja bem, isso no caso do driver do MySQL. Pode ser que ele passasse as consulta com ? para o banco e deixasse o trabalho de bindagem com o banco de dados.)
Creio que o erro venha daí. Mas, nome de tabela não é pra ser passado como bind variable, mas sim como literal. Você deve fornecer uma query válida já com o nome da tabela e setar somente as variáveis.
Continuo batendo na tecla de fazer na mão. Tomando as devidas precauções, já que o dado vem de uma fonte não confiável (usuário).
[quote=Luiz Henrique Coura]Utilizo MySQL e ele acusou esse erro.
Pensei nessa solução do Maurício. O problema é q terei q ficar adicionando uma query nova para cada tabela nova q entrar.
Estou pensando em fazer filtrar os parâmetros passados pelo o usuário.
Zeh, gostaria de ler mais sobre bind variables, enfim, sobre essa característica do banco. Onde consigo encontrar?
[/quote]
Use Hibernate :mrgreen:
Use Hibernate :mrgreen:
Use Hibernate :mrgreen:
Use Hibernate :mrgreen:
Use Hibernate :mrgreen:
E bind variables é o que você faz quando dá um setQualquerCoisa() num prepared statement, você está “ligando” ou “posicionando” variáveis dentro da sua query.
Mas…
Use Hibernate :mrgreen:
Use Hibernate :mrgreen:
Use Hibernate :mrgreen:
public class NomeClasse {
public ResultSet queryTableByStatus(Connection con, String table,
Integer status) throws SQLException {
// Cria o seu patern
String sqlPatern = new String("select * from {0} where status = ?");
// Muda o primeiro parâmetro com o nome da tabela
String sql = format(sqlPatern, (Object) new String[] { table });
// Faz a chamada para o prepare
PreparedStatement ps = con.prepareStatement(sql);
// Preenche as variáveis do statement
ps.setInt(1, status);
// Executa a sua query
ResultSet rs = ps.executeQuery();
return rs;
}