我正在将 Postgres 列的类型从UUID
更改TEXT
为
ALTER TABLE my_table ALTER COLUMN id TYPE TEXT;
但我想确保我的代码适用于两种列类型。即因为很难将数据库的更改与在服务器上运行的代码同步。
我正在通过在类型之间切换来进行本地测试。这可以通过移回 UUID 来完成(当数据格式正确时)
ALTER TABLE my_table ALTER COLUMN id TYPE UUID USING id::uuid;
这行得通。但是当切换到 aTEXT
并运行我的 Java 代码时,我注意到测试中有一些失败。特别是当一个WHERE
语句使用switched时id
。例如
UPDATE my_table SET name = 'new_name' WHERE id = '00000000-0000-0000-0001-000000000000'::uuid;
生成
ERROR: operator does not exist: text = uuid
这对我来说很有意义,因为namedParameterJdbcTemplate
我正在使用的类是::uuid
在 SQL 查询的 id 末尾添加一个。我不确定它为什么要这样做,但可以通过将传入的参数从 UUID 转换为字符串来解决它。
但是,如果我将列切换回UUID
我会收到以下错误
UPDATE my_table SET name = 'new_name' WHERE id = '00000000-0000-0000-0001-000000000000';
生成
ERROR: operator does not exist: text = uuid
我可以接受导致问题的第一个更新查询,因为我可以在psql
命令行上运行它并得到相同的错误。然而,这不会发生在第二个命令中psql
。
此外,如果我停止使用namedParameterJdbcTemplate
's 参数并将值烘焙到 sql 字符串中,它就可以工作。
String sqlStatement = "UPDATE my_table SET name = :v_new_name WHERE id = :v_id";
MapSqlParameterSource sqlParameterMap = new MapSqlParameterSource();
sqlParameterMap.addValue("v_new_name", "New Name");
sqlParameterMap.addValue("v_id", id.toString());
namedParameterJdbcTemplate.update(sqlStatement, sqlParameterMap);
生成
错误:运算符不存在:uuid = 字符变化
从SQLStateSQLExceptionTranslator.java
.
相对
String sqlStatement = "UPDATE my_table SET name = 'New Name' WHERE id = '" + id.toString() + "'";
MapSqlParameterSource sqlParameterMap = new MapSqlParameterSource();
namedParameterJdbcTemplate.update(sqlStatement, sqlParameterMap);
哪个有效。
为什么会这样?感觉就像在做namedParameterJdbcTemplate
一些我找不到的额外类型检查。