1

我在 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 中找到更好的选择。

感谢您的任何意见,李

4

2 回答 2

2

我认为您不能将命名参数用于数据库标识符,例如表名。只有值表达式。如果允许,它会使您容易受到 SQL 注入攻击。作为替代方案,您可以用 Java 构造查询。

于 2009-08-14T15:11:37.190 回答
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 相同。

于 2009-08-14T13:51:28.197 回答