2

可能重复:
使用休眠查询:冒号被视为参数/转义冒号

我们正在尝试编写本机查询。当我们尝试更新包含 的特定列值时,": "会出现异常。

这是生成的查询

  UPDATE MY_TABLE SET DESCRIPTION = "Test 01 : ABC",LAST_UPDATE_TS =
  CURRENT_TIMESTAMP ,LAST_UPDATE_USER_ID = 111 WHERE MY_ID =123 

我认为问题在于DESCRIPTION数据,其中包含': '

我们得到这个错误

 nested exception is org.hibernate.QueryException:Space is not allowed after 
 parameter prefix ':' ' UPDATE 
 MY_TABLE SET DESCRIPTION = "MY Test 01 : ABC",LAST_UPDATE_TS =
 CURRENT_TIMESTAMP, LAST_UPDATE_USER_ID = 111 WHERE MY_ID =123'

这是负责查询的 Java 代码:

 StringBuffer strQry = new StringBuffer(" UPDATE MY_TABLE SET ");

          if(myForm.getDescription() != null){
                 if(flag == 1){
                       strQry.append(",");
                 }
                 strQry.append(" DESCRIPTION = \"" + myForm.getDescription().trim()+ "\" ");
                 flag = 1;

知道为什么会发生此错误以及我们如何解决它吗?

4

3 回答 3

1
UPDATE MY_TABLE SET DESCRIPTION = "Test 01 \\: ABC",LAST_UPDATE_TS =
  CURRENT_TIMESTAMP ,LAST_UPDATE_USER_ID = 111 WHERE MY_ID =123

添加正斜杠。

冒号用于指定命名参数,因此您必须转义它(然后转义转义)。

于 2012-11-11T15:41:45.150 回答
0

我认为您的情况出现问题是因为 Hibernate 认为您正在使用命名参数(符号“:”是用于此的特殊关键字)。尝试将描述、last_update_user_id 和 my_id 定义为查询的命名参数。所以你的代码看起来像:

String queryText = "UPDATE MY_TABLE SET DESCRIPTION = :description,LAST_UPDATE_TS =
  CURRENT_TIMESTAMP, LAST_UPDATE_USER_ID = :lastUpdateUserID WHERE MY_ID = :myId";
Query query = session.createSQLQuery(queryText);
query.setParameter("description", yourDescription);
query.setParameter("lastUpdateUserID", yourLastUpdateUserID);
query.setParameter("myId", yourMyId);
...

在我的示例中,我在一个地方定义了整个查询,但您可以通过代码片段中的部分来构建它:

 StringBuffer strQry = new StringBuffer(" UPDATE MY_TABLE SET ");

 if(myForm.getDescription() != null){
     if(flag == 1){
           strQry.append(",");
     }
     strQry.append(" DESCRIPTION = :description ");
     flag = 1;
 } 
...

编辑

在您的条件下,在查询中使用数字参数 (?1) 可能会更好。例子:

 List<Object> parametersList = new LinkedList<Object>();
 int parameterPosition = 1;

 StringBuffer strQry = new StringBuffer(" UPDATE MY_TABLE SET ");

 if(myForm.getDescription() != null){
     if(parameterPosition > 1){
           strQry.append(",");
     }
     strQry.append(" DESCRIPTION = ?");
     strQry.append(parameterPosition);
     strQry.append(" ");

     parametersList.add(myForm.getDescription().trim());
     parameterPosition ++;
 } 
...

int position = 1;
for (Object parameter: parametersList) {
     query.setParameter(position, parameter);
     position++;
}

至少有点像这样)。

于 2012-11-11T17:39:30.673 回答
0

你需要参数化你的sql。":" 是 hibernate 用来检测命名参数的特殊字符。因此,hibernate 在尝试解析查询时会引发异常。
您可以参数化如下所示的 sql。

   StringBuffer strQry = new StringBuffer(" UPDATE MY_TABLE SET ");

          if(myForm.getDescription() != null){
                 if(flag == 1){
                       strQry.append(",");
                 }
                 strQry.append(" DESCRIPTION = :description");
                 flag = 1;
....

   if(myForm.getDescription() != null){
        session.setString("description", description)
   }

参数化查询很重要,还有两个原因 -

  1. 避免sql注入。
  2. 由于您的 sql 的预编译,性能提升。
于 2012-11-11T17:27:52.430 回答