我在Hibernate中有以下命名查询:
<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中发现任何更好的选择。
感谢任何输入, 利
答案 0 :(得分:2)
我认为您不能将命名参数用于表名等数据库标识符。只有值表达式。如果允许,它会使您容易受到SQL注入攻击。作为替代方案,您可以使用Java构建查询。
答案 1 :(得分:0)
您使用的数据库类型是什么?有些数据库区分大小写(实际上大多数都是微软的)。所以名为'wibble'的表与'WiBbLe'不同,仍然与'WIBBLE'不同。
当您创建一个名为wibble且没有引号的表时,大多数数据库(如Oracle)会将其创建为以全部大写“WIBBLE”命名的表。当您查询它时,您可以像在此处一样使用它:
SELECT * FROM wibble
数据库会将此解释为“WIBBLE”并且没有问题。
持久性提供程序似乎总是把它放在引号中。要使引用的名称与创建的名称相同,您应该将其大写。所以试试这个:
getSession().getNamedQuery(CREATE_SQL).setString(CREATE_SQL_TABLE_NAME_PARAM, "WIBBLE").executeUpdate();
这应该创建带有'WIBBLE'的语句,该语句应该与没有引号的wibble相同。