Проблемы с именем таблицы При вызове Именованного запроса в режиме гибернации
-
16-09-2019 - |
Вопрос
У меня есть следующий именованный запрос в режиме гибернации:
<sql-query name="CreateLogTable">
CREATE TABLE IF NOT EXISTS :tableName (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`url` VARCHAR (750) NOT NULL,
`query` VARCHAR (500),
`ipaddress` VARCHAR (39),
`datetime` DATETIME NOT NULL,
`hits` MEDIUMINT UNSIGNED DEFAULT '0' NOT NULL,
`path_id` VARCHAR (8),
PRIMARY KEY(`id`),
UNIQUE(`id`),
INDEX(`id`,`query`,`datetime`,`path_id`)
) TYPE = MyISAM
</sql-query>
Затем я пытаюсь выполнить эту строку, используя следующую строку (константы указывают на правильные элементы):
getSession().getNamedQuery(CREATE_SQL).setString(CREATE_SQL_TABLE_NAME_PARAM, "wibble").executeUpdate();
Теперь, когда я выполняю код, я получаю ошибку SQL относительно имени таблицы, которое выводится в кавычках:
CREATE TABLE IF NOT EXISTS 'wibble' (
Если я возьму сгенерированный запрос и попробую выполнить его без кавычек вокруг имени таблицы, запрос сработает нормально.Это просто те цитаты, которые вызывают мою проблему.
Итак, мой вопрос заключается в следующем:Что мне нужно использовать вместо setString
чтобы убедиться, что мой параметр не заключен в кавычки?Я пытался setParameter
мне не повезло, и я не смог найти лучшей альтернативы из API.
Спасибо за любой вклад, Ли
Решение
Я не думаю, что вы можете использовать именованные параметры для идентификаторов базы данных, таких как имена таблиц.Только выражения значений.Если бы это было разрешено, это сделало бы вас уязвимыми для атак с использованием SQL-инъекций.В качестве альтернативы вы могли бы создать запрос на Java.
Другие советы
Какой тип базы данных вы используете?Некоторые базы данных чувствительны к регистру (на самом деле большинство из них чувствительны, за исключением Microsoft).Таким образом, таблица с именем "wibble" отличается от "WiBbLe" и все еще отличается от "WIBBLE".
Когда вы создаете таблицу с именем wibble без кавычек, большинство баз данных, таких как Oracle, создают ее как таблицу с именем со всеми заглавными буквами "WIBBLE".Когда вы запрашиваете его, вы используете его так, как вы делаете здесь:
SELECT * FROM wibble
База данных интерпретировала бы это как "КОЛЕБАНИЕ", и проблем не возникло бы.
Поставщик сохраняемости, похоже, всегда заключает это в кавычки.Чтобы имя, заключенное в кавычки, оставалось таким же, как оно было создано, вы должны написать его заглавной буквой.Так что попробуйте это:
getSession().getNamedQuery(CREATE_SQL).setString(CREATE_SQL_TABLE_NAME_PARAM, "WIBBLE").executeUpdate();
Это должно создать оператор с 'WIBBLE', который должен быть таким же, как wibble, без кавычек.