2010-05-26 52 views
10

Estoy intentando utilizar un PreparedStatement con un código similar a este:PreparedStatement.setString() sin comillas

SELECT * FROM ? WHERE name = ? 

Obviamente, lo que sucede cuando uso setString() para establecer el campo de tabla y el nombre es esto:

SELECT * FROM 'my_table' WHERE name = 'whatever' 

y la consulta no funciona. ¿Hay una manera de establecer la cadena sin comillas para que la línea se ve así:

SELECT * FROM my_table WHERE name = 'whatever' 

o debo renunciar a ella y utilizar la instrucción regular en vez (los argumentos vienen de otra parte del sistema, ninguno de los dos ésos es ingresado por un usuario)?

+0

El hecho de que usted está contemplando hacer esto me sugiere que usted debe considerar la remodelación de sus datos. Quizás debería hacer una vista que combine todas las tablas, con una columna añadida como el 'nombre de la tabla'. – nsayer

Respuesta

15

Los parámetros no se pueden usar para parametrizar la tabla ni para parametrizar ningún objeto de base de datos. Se usan principalmente para parametrizar cláusulas WHERE/HAVING.

Para hacer lo que quiera, tendrá que hacer la sustitución usted mismo y crear una declaración regular según sea necesario.

Cuando utiliza una instrucción preparada, esta es una sugerencia para que la base de datos realice el procesamiento inicial en la instrucción, p. Ej. analizar la cadena y posiblemente determinar un plan de ejecución. Si los objetos usados ​​en la consulta pueden cambiar dinámicamente, entonces la base de datos no podría hacer mucha preparación inicial.

+0

Para avanzar en esto, no es que usar setString ponga comillas alrededor de las cadenas, porque no lo hace (las variables de enlace no funcionan de esa manera). Es solo que no puedes usar una variable para esa parte de la consulta. – Donnie

+0

¡Lo tengo, gracias! ¿Diría que usar PreparedStatement no tiene mucho sentido aquí, dado que los parámetros no son ingresados ​​por el usuario? Quiero decir que es probablemente más costoso en comparación con el uso de Declaración regular. ¿O debería usar PreparedStatement en todas partes sin importar qué? – Slavko

+1

Aún puede usar un Estado Preparado, simplemente no intente parametrizar el nombre de la tabla - parametrizar el 'quien sea'. Existe cierto debate sobre el uso de declaraciones preparadas frente a declaraciones regulares, pero creo que el consenso es usar declaraciones preparadas a menos que descubra buenas razones para no hacerlo. – mdma

2

Desafortunadamente no se pueden parametrizar los nombres de las tablas para las declaraciones preparadas. Si lo desea, puede construir una cadena y ejecutarla como SQL dinámico.

3

Dudo que su SQL sea realmente infinitamente flexible de esa manera. Solo tiene un número finito de tablas, por lo que el número de cadenas finales estáticas para expresar el SQL que necesita también es finito.

Siga usando PreparedStatement y enlace sus variables. Vale la pena, especialmente útil para evitar problemas de inyección de SQL.

+0

Tiene obvio que no leyó lo suficiente TheDailywtf.com. Tener una tabla por cliente (y la cantidad de clientes no está vinculada) es un patrón anti usado. –

+0

Aparentemente no. Gracias por el aviso. 8) – duffymo

2

El error que cometió es que no puede pasar el nombre de la tabla como parámetro. Solo debe pasar los valores a una instrucción SQL.

Ex: Si eres wantto:

Select * from LoggedUsers where username='whatever' and privilege='whatever'; 

entonces has de construir PreparedStatement como:

Select * from LoggedUsers where username=? and privilege=? 

setString(1, usernameObject); 
setString(2, privilegeObject); 

El propósito de PreparedStatement es reducir la dificultad y la legibilidad de el código de conexión de la base de datos. cuando el desarrollador tiene que usar tantos valores de columna con la instancia de Statement es tan difícil poner punto y coma, comas y más (operador concat).

Creo que estás por error quería tomar ventaja de ella, que no está diseñado para ser ....

Cuestiones relacionadas