2010-05-26 4 views
10

Я пытаюсь использовать PreparedStatement с кодом, похожее на это:PreparedStatement.setString() без кавычек

SELECT * FROM ? WHERE name = ? 

Очевидно, что происходит, когда я использую SetString() для установки таблицы и имя поля это:

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

и запрос не работает. Есть ли способ, чтобы установить строку без кавычек, поэтому строка выглядит следующим образом:

SELECT * FROM my_table WHERE name = 'whatever' 

или я должен просто отказаться от него и использовать регулярные заявления вместо (аргументы приходят от другой части системы, ни один из они вводятся пользователем)?

+0

Тот факт, что вы намерены делать это наводит меня на мысль, что вы должны рассмотреть ремоделирования данные. Возможно, вы должны сделать представление, которое объединяет все таблицы, а добавленный столбец - «имя таблицы». – nsayer

ответ

15

Параметры не могут использоваться для параметризации таблицы или параметризации любых объектов базы данных. Они в основном используются для параметризации предложений WHERE/HAVING.

Чтобы сделать то, что вы хотите, вам нужно будет сделать замену самостоятельно и при необходимости создать регулярный оператор.

Когда вы используете подготовленный оператор, это подсказка для базы данных, которая обрабатывает переднюю обработку в инструкции. проанализируйте строку и, возможно, определите план выполнения. Если объекты, используемые в запросе, могут динамически меняться, то база данных не могла бы сильно подгонять.

+0

Чтобы это не сделать, использование setString ставит кавычки вокруг строк, потому что это не так (привязка переменных не работает именно так). Просто вы не можете использовать переменную для этой части запроса. – Donnie

+0

Получил, спасибо! Не могли бы вы сказать, что использование PreparedStatement не имеет смысла здесь, учитывая, что паразиты не введены пользователем? Я имею в виду, что это, вероятно, более дорогостоящее, чем обычное заявление. Или я должен использовать PreparedStatement везде, несмотря ни на что? – Slavko

+1

Вы все еще можете использовать PreparedStatement, просто не пытайтесь параметризовать имя таблицы - параметризуете «кто бы то ни было». Существует некоторая дискуссия относительно использования подготовленных и регулярных заявлений, но я считаю, что консенсус состоит в том, чтобы использовать подготовленные заявления, если вы не обнаружите веских причин не делать этого. – mdma

2

К сожалению, вы не можете параметризовать имена таблиц для подготовленных операторов. При желании вы можете построить String и выполнить его как динамический SQL.

3

Я сомневаюсь, что ваш SQL действительно бесконечно гибкий. У вас есть только конечное число таблиц, поэтому число статических окончательных строк для выражения SQL, в котором вы нуждаетесь, также конечно.

Продолжайте использовать PreparedStatement и привяжите переменные. Это стоит того, что особенно полезно при устранении проблем с SQL-инъекциями.

+0

У вас очевидно, что недостаточно читать TheDailywtf.com. Наличие таблицы на клиента (а количество клиентов не привязано) является используемым анти-шаблоном. –

+0

Видимо, нет. Спасибо за головы. 8) – duffymo

2

Ошибка, которую вы сделали, состоит в том, что вы не можете передать имя таблицы в качестве параметра. Вы должны передавать значения только в SQL-заявление.

Ex: Если вы wantto:

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

тогда вы, чтобы построить PreparedStatement как:

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

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

Цель PreparedStatement заключается в снижении сложности и читаемость код подключения к базе данных., когда разработчику приходится использовать так много значений столбцов с экземпляром Statement, так сложно поставить точки с запятой, запятыми и плюсом (оператор concat).

Я думаю, что вы по ошибке хотели воспользоваться ею, который не предназначен быть ....

Смежные вопросы