向 DB2 Z/OS PreparedStatement 插入/更新十六进制值

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

我需要用 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()
来解压id
SELECT HEX(COLUMN) FROM TABLE
,结果将是“02658947530232010038892587183C”。

java hex prepared-statement db2-zos
1个回答
0
投票

你为什么不直接从 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();
}
© www.soinside.com 2019 - 2024. All rights reserved.