Java postgres中ctid的JDBC类型是什么?

Java postgres中ctid的JDBC类型是什么?,java,postgresql,jdbc,prepared-statement,Java,Postgresql,Jdbc,Prepared Statement,我似乎无法在准备好的语句中设置正确的类型。此代码: String sql = "delete from foo where ctid = ?"; PreparedStatement deleteStmt = conn.prepareStatement( sql ); deleteStmt.setString(1, "(0,43)"); // select ctid from foo shows (0,43) exists.... int a = deleteStmt.executeUpdate

我似乎无法在准备好的语句中设置正确的类型。此代码:

String sql = "delete from foo where ctid = ?";
PreparedStatement deleteStmt = conn.prepareStatement( sql );
deleteStmt.setString(1, "(0,43)");  // select ctid from foo shows (0,43) exists....
int a = deleteStmt.executeUpdate();
引发此异常:

org.postgresql.util.PSQLException: ERROR: operator does not exist: tid = character varying
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.   Position: 28
请注意,在psql中,delete使用字符串:

mydb=# DELETE FROM foo where ctid = '(0,43)';
DELETE 1

JDBC PreparedStatement中tid的正确类型/编码是什么?我尝试过setRowId()(throws ava.sql.SQLFeatureNotSupportedException:Method org.postgresql.jdbc4.Jdbc4PreparedStatement.setRowId(int,RowId)尚未实现。)和setBytes()(throws…运算符不存在:tid=byte)

已解决!您必须手动创建一个PGO对象,设置类型和值,并将其作为对象传递给JDBC。现在可以这样做了:

sql = "delete from foo where ctid = ?";
deleteStmt = conn.prepareStatement( sql );
org.postgresql.util.PGobject pgo = new org.postgresql.util.PGobject();
pgo.setType("tid");
pgo.setValue("(0,54)");  // value is a string as might be returned in select ctid from foo and then resultSet.getString(1);
deleteStmt.setObject(1, pgo);

int a = deleteStmt.executeUpdate();
System.out.println("delete returns " + a);

老话题,但我想补充一下

where ctid = ?::tid";
而不是

where ctid = ?::ctid";

成功了。然后可以使用PreparedStatement.setString(x,“(10,3)”)

如果您尝试使用
deleteStmt.setObject(1,”(0,43)”,会发生什么?它会引发什么异常?另一种可能的解决方案:
setString(1),(0,43)::ctid”)
或不使用PreparedStatement并使用动态SQL。setObject(1),(0,43)”)和setString(1),(0,43)::ctid”)都会引发org.postgresql.util.PSQLException:错误:运算符不存在:tid=字符变化。在PreparedStatement上不进行替换的动态SQL(例如SQL=“delete from foo where ctid=”(0,50)”;deletesmt=conn.prepareStatement(SQL);)可以工作。否则-如果可能,将数据类型更改为varcharctid是类型为tid的内部列,无法更改。