尝试使用本机SQL更新数据时出现此错误。这是我的剧本:
update weight_note_receipt set pledge_id =:pledge where wn_id in (:wns)
wns
是包含多个wn_id
的字符串,如下所示:
222,226,228,251,256,262,263,264,265,266,267,272,281,286,294,296,299,301,302,303,306,307,330,332,333,337,338,339,341,368,371,376,377,378,379,380,381,385,391,397,423,424,443,452,454,461,462,463,464,490,503,504,521,525,528,529,530,532,533,549,554,560,561,564,565,566,567,569,570,595,598,600,603,605,606,607,644,646,649,653,661,662,663,667,669,678,683,752,1039,1075,258,259,260,261,268,269,270,287,304,305,308,325,334,604,643,647,648,659,660,664,665,666,704,709,753,754,757,758,809,834,846,861,872,879,882,911,913,916,919,920,164
当我更新(使用query.executeUpdate()
)时,它会抛出以下错误:
请求处理失败;嵌套异常是org.hibernate.exception.DataException:无法执行本机批量 具有根本原因的操纵查询 com.mysql.jdbc.MysqlDataTruncation:数据截断:截断错误的DOUBLE值: ' 222,226,228,251,256,262,263,264,265,266,267,272,281,286,294,296,299,301,302,303,306,307,330,332,333,337,338,339,341,368,371,376,'
是因为输入字符串太长了吗?
答案 0 :(得分:10)
在数据库(预准备语句)中进行参数化查询时,为参数赋值绝不能改变查询的结构和执行路径(否则数据库不会将它们视为参数化查询并抛出异常)。
这就是为什么你不能为以下查询准备好的语句:
select * from myTable order by ?
select id, f1, ? from myTable
select * from ?
。因为为每个参数赋值会改变查询执行路径(请记住,预处理语句的查询会被解析一次并产生单个执行路径)。
相同的规则适用于Hibernate查询解析器,您不应为参数分配更改查询结构的值。
将值1, 2, 3
的字符串分配给SHOULD-TO-BE-A-NUMBER参数是一样的,实际上第一个查询的翻译方式与update weight_note_receipt set pledge_id =:pledge where wn_id = :wns
相同但是第二个一个将被翻译为update weight_note_receipt set pledge_id =:pledge where (wn_id = :x1 or wn_id = :x2 or wn_id = :x3)
,显然是具有不同执行路径的不同查询。
所以即使Hibernate没有抛出异常,你的数据库也会。
答案 1 :(得分:2)
如果您使用的是SQLQuery Hibernate API,则可以使用setParameterList(PARAM, COLLECTION)
方法。
您的查询字符串可以与其in
子句和大括号保持一致。
答案 2 :(得分:0)
如果客户端发送的数据大小超过数据库中指定的大小,则抛出org.hibernate.exception.GenericJDBCException:无法在org.hibernate.exception.SQLStateConverter.handledNonSpecificException中执行本机批量操作查询。