Java,JDBC INSERT ON DUPLICATE KEY UPDATE wild cards

问题描述 投票:0回答:1

我有下一个 SQL 查询:

const val INSERT_OR_UPDATE_ITEM_SQL = "" +
            "INSERT INTO `items` (owner_id, object_id, item_id, count, enchant_level, item_location, item_location_data, custom_type1, custom_type2, duration_left, create_time)" +
            "VALUES (?,?,?,?,?,?,?,?,?,?,?) " +
            "ON DUPLICATE KEY UPDATE owner_id=?,object_id=?,item_id=?,count=?,enchant_level=?,item_location=?,item_location_data=?,custom_type1=?,custom_type2=?,duration_left=?,create_time=?"

这是 PreparedStatement 的准备:

statement.setString(1, item.ownerId)
statement.setInt(2, item.objectId)
statement.setInt(3, item.template.id)
statement.setInt(4, item.count)
statement.setInt(5, item.enchantLevel)
statement.setString(6, item.itemLocation.name)
statement.setInt(7, item.itemLocationData)
statement.setInt(8, item.customType1)
statement.setInt(9, item.customType2)
statement.setInt(10, item.durationLeft)
statement.setLong(11, item.createTime)

这里的问题是当我尝试执行查询时:

Exception in thread "main" java.sql.SQLTransientConnectionException: (conn=352) Parameter at position 12 is not set

这是因为我有 22 个问题标记而不是 11 个(因为 ON CONFLICT UPDATE)

我的简单任务是制作 INSERT 或 UPDATE

java mysql mariadb sql-update sql-insert
1个回答
3
投票

就您的查询而言,(某些)参数需要传递两次(一次用于插入,另一次用于更新)。 MySQL 提供

VALUES(...)
函数 以在更新子句中按列名访问插入值 - 这正是为您省去麻烦。

此外:如果只针对非主键列而不是所有列,则

UPDATE
子句会更好地表达。

假设您的表有列

owner_id, object_id, item_id, cnt, enchant_level
,其中前三列是主键:

insert into items (owner_id, object_id, item_id, cnt, enchant_level)
values (?, ?, ?, ?, ?)
on duplicate key update 
set cnt = values(cnt), 
    enchant_level = values(enchant_level)

或者,如果您运行的是 MySQL 8.0.19 或更高版本,则可以使用新的基于别名的语法(

values()
在 MySQL 中是一个不幸的名称选择,因为它在某种程度上与同音异义 SQL 标准行构造函数冲突):

insert into items (owner_id, object_id, item_id, cnt, enchant_level)
values (?, ?, ?, ?, ?) v
on duplicate key update 
set cnt = v.cnt,
    enchant_level = v.enchant_level
© www.soinside.com 2019 - 2024. All rights reserved.