我需要用 Java 中的 PreparedStatement 在我的数据库中插入一个十六进制值。
我可以使用十六进制函数进行选择以获得我的价值:
String id = "02658947530232010038892587183C";
String request = "SELECT HEX(COLUMN) FROM TABLE WHERE HEX(COLUMN)=?";
Connection con = getConnectionDb2z();
ResultSet rs = null;
try(PreparedStatement select = con.prepareStatement(request))
{
insert.setString(1, id);
rs = select.executeQuery();
rs.next();
System.out.println(rs.getString("COLUMN"));
}
catch(SQLException e)
{
throw e;
}
finally
{
con.close();
}
我的结果是
02658947530232010038892587183C.
(这是一个例子)
但是现在我想在我的表中插入一个值。 如果我尝试:
String id = "02658947530232010038892587183C";
String request = "INSERT INTO TABLE (COLUMN) VALUES (X'?')";
Connection con = getConnectionDb2z();
try(PreparedStatement insert = con.prepareStatement(request))
{
insert.setString(1, id);
insert.executeUpdate();
}
Java 无法识别来自“(X'?')` 的
?
参数,我有一个错误:
线程“main”中的异常 com.ibm.db2.jcc.am.SqlSyntaxErrorException:参数无效。
如果我尝试:
String id = "X'02658947530232010038892587183C'";
String request = "INSERT INTO TABLE (COLUMN) VALUES (?)";
Connection con = getConnectionDb2z();
try(PreparedStatement insert = con.prepareStatement(request))
{
insert.setString(1, id);
insert.executeUpdate();
}
我也得到一个错误:
线程“main”中的异常 com.ibm.db2.jcc.am.SqlDataException:DB2 SQL 错误:SQLCODE=-302,SQLSTATE=22001
因为它试图将
X'0038892587183C'
作为字符串插入。
我发现工作的唯一方法是:
String id = "02658947530232010038892587183C";
String request = "INSERT INTO TABLE (COLUMN) VALUES (X'?')";
Connection con = getConnectionDb2z();
try(PreparedStatement insert = con.prepareStatement(request.replace("?", id))
{
insert.executeUpdate();
}
但是,这种方法是行不通的。有没有办法正确地做到这一点?
提醒一下,我的数据库是 DB2 Z/OS,函数 UNHEX 不存在。
更多说明:
在我的要求中,
X'?'
是一个用于打包十六进制值的函数。
我的
COLUMN
里的长度TABLE
是7,我的id
的长度是14,我需要打包这个id把他插入我的bdd。当我想在我的 java 代码中阅读它时。
我用函数
HEX(id)
解压 id。但是在 DB2 Z/OS 中函数 UNHEX
不存在,我们需要使用 X'id'
,但是正如您所看到的 PreparedStatement
没有将其识别为函数。
当我用函数
X''
打包这个id“02658947530232010038892587183C”时,数据库中带有SELECT COLUMN FROM TABLE
的结果是Áiåë�i g
(你看到的结果与我得到的不完全一样,因为有些字符是网站无法读取的) .
如果我在我的选择中使用函数
HEX()
来解压idSELECT HEX(COLUMN) FROM TABLE
,结果将是“02658947530232010038892587183C”。
你为什么不直接从 Java 转换它呢?
String id = "0038892587183C";
int idAsInt=Integer.parseInt(id, 16);
String request = "INSERT INTO TABLE (COLUMN) VALUES (?)";
Connection con = getConnectionDb2z();
try(PreparedStatement insert = con.prepareStatement(request))
{
insert.setInt(1, idAsInt);
insert.executeUpdate();
}
这将
id
从十六进制转换为 int
使用 Integer.parseInt
使用自定义基数 16
以便将其解析为十六进制数。
然后,它使用
PreparedStatement#setInt
来设置参数而没有X''
。
如果您的十六进制数超过
int
的有符号 32 位限制,您需要使用 long
(有符号 64 位)或 BigInteger
。不幸的是,JDBC 不允许直接传递 BigInteger
,因此您需要使用像 these mentioned here 这样的解决方案:
String id = "0038892587183C";
BigInteger idAsBigInt=new BigInteger(id, 16);//parse it to a BigInteger
String request = "INSERT INTO TABLE (COLUMN) VALUES (?)";
Connection con = getConnectionDb2z();
try(PreparedStatement insert = con.prepareStatement(request))
{
insert.setBigDecimal(1, new BigDecimal(idAsBigInt));//or possibly insert.setString(1, String.valueOf(idAsBigInt));
insert.executeUpdate();
}