2

重複の可能性:
Hibernateクエリの使用:コロンはパラメーターとして扱われます/コロンをエスケープします

ネイティブクエリを作成しようとしています。を含む特定の列の値を更新しようとすると": "、例外が発生します。

これは生成されたクエリです

  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 が名前付きパラメーターを使用していると見なすため、問題が発生すると思います (記号 ":" は、これに使用される特別なキーワードです)。description、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);
...

私の例では、クエリ全体を 1 か所で定義していますが、コード スニペットのように部分ごとに構築することもできます。

 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)
   }

クエリをパラメータ化することは、他に 2 つの理由から重要です。

  1. SQL インジェクションを回避します。
  2. SQL の事前コンパイルにより、パフォーマンスが向上します。
于 2012-11-11T17:27:52.430 に答える