Java:在 DB2 SQL 查询中将数组设置为参数名称时出现问题
Java: Problems while setting an array as parameter name in DB2 SQL query
DB2 驱动程序版本:4.19.66
DB2安装版本:DB2 v11.5.7.0
Java 版本: 1.8_121
我正在尝试在 DB2 SQL 查询上设置参数:
SELECT distinct object_id AS oid
FROM myschema.package p
INNER JOIN myschema.package_item pi ON p.machine_id = pi.machine_id
AND p.package_id = pi.package_id
INNER JOIN main_schema.item i ON i.item_id = pi.id_articulo
WHERE p.package_status_id = 5 AND p.machine_id IN (:machineIdsParam)
我必须说 p.machine_id 是 DB2 数据库中的一个 INTEGER 字段。
我这样准备连接:
Properties properties = new Properties(); // Create Properties object
properties.put("user", config.getDbUser()); // Set user ID for connection
properties.put("password", bdPassword); // Set password for connection
properties.put("enableNamedParameterMarkers", 1);
connection = (DB2Connection) DriverManager.getConnection(config.getDbUrl(), properties);
然后我尝试在此查询中设置参数:
DB2PreparedStatement ps = connection.getPreparedStatement(sqlString);
List<Integer> machineIds = Array.asList(new Integer[] { 1, 5, 7, 9});
Array machineIdArray = connection.createArrayOf("INTEGER", machineIds.toArray(new Integer[idInstalaciones.length]));
ps.setJccArrayAtName("machineIdsParam", machineIdArray);
但是我收到这个错误:
com.ibm.db2.jcc.am.SqlSyntaxErrorException: [jcc][1091][10417][4.19.66] Invalid data conversion: Parameter instance com.ibm.db2.jcc.am.o@36fc695d is invalid for the requested conversion.
我找不到关于如何使用此 setJccArrayAtName() 的示例,只有我无法找到此错误原因的文档。我只是猜测它与数据类型有关,但我不知道如何使它起作用。
我认为 Db2 的任何系列都不支持带有 IN
谓词的数组..
通常需要的是单独的参数
SELECT distinct object_id AS oid
FROM myschema.package p
INNER JOIN myschema.package_item pi ON p.machine_id = pi.machine_id
AND p.package_id = pi.package_id
INNER JOIN main_schema.item i ON i.item_id = pi.id_articulo
WHERE p.package_status_id = 5 AND p.machine_id IN (:machineId1
,:machineId2
,:machineId3
,:machineId4
)
这当然要求您提前知道需要多少个值,或者至少知道某个最大数量。 (您始终可以加载任何剩余参数中的最后一个值。)
另一种选择是传递分隔字符串,该字符串被分割成单独的值。像这样(假设一个逗号分隔列表)
SELECT distinct object_id AS oid
FROM myschema.package p
INNER JOIN myschema.package_item pi ON p.machine_id = pi.machine_id
AND p.package_id = pi.package_id
INNER JOIN main_schema.item i ON i.item_id = pi.id_articulo
WHERE p.package_status_id = 5 AND p.machine_id IN (select int(element)
from table (systools.split(:machineIds, ' '))
)
systools.split() 可能特定于 IBM i 的 Db2,其他平台可能在不同的架构中有它。
如果不出意外,您可以编写自己的用户定义函数 (UDF) 来进行拆分。
对于 LUW 的 Db2:
... IN
(
SELECT TOK
FROM XMLTABLE
(
'for $id in tokenize($s, ",") return <i>{string($id)}</i>'
PASSING CAST (:machineIdsParam AS VARCHAR (100)) AS "s"
COLUMNS
TOK INT PATH '.'
)
)
您为 :machineIdsParam
参数传递了类似“1,2,3”的字符串。即:以逗号分隔的 int 值。
DB2 驱动程序版本:4.19.66
DB2安装版本:DB2 v11.5.7.0
Java 版本: 1.8_121
我正在尝试在 DB2 SQL 查询上设置参数:
SELECT distinct object_id AS oid
FROM myschema.package p
INNER JOIN myschema.package_item pi ON p.machine_id = pi.machine_id
AND p.package_id = pi.package_id
INNER JOIN main_schema.item i ON i.item_id = pi.id_articulo
WHERE p.package_status_id = 5 AND p.machine_id IN (:machineIdsParam)
我必须说 p.machine_id 是 DB2 数据库中的一个 INTEGER 字段。
我这样准备连接:
Properties properties = new Properties(); // Create Properties object
properties.put("user", config.getDbUser()); // Set user ID for connection
properties.put("password", bdPassword); // Set password for connection
properties.put("enableNamedParameterMarkers", 1);
connection = (DB2Connection) DriverManager.getConnection(config.getDbUrl(), properties);
然后我尝试在此查询中设置参数:
DB2PreparedStatement ps = connection.getPreparedStatement(sqlString);
List<Integer> machineIds = Array.asList(new Integer[] { 1, 5, 7, 9});
Array machineIdArray = connection.createArrayOf("INTEGER", machineIds.toArray(new Integer[idInstalaciones.length]));
ps.setJccArrayAtName("machineIdsParam", machineIdArray);
但是我收到这个错误:
com.ibm.db2.jcc.am.SqlSyntaxErrorException: [jcc][1091][10417][4.19.66] Invalid data conversion: Parameter instance com.ibm.db2.jcc.am.o@36fc695d is invalid for the requested conversion.
我找不到关于如何使用此 setJccArrayAtName() 的示例,只有我无法找到此错误原因的文档。我只是猜测它与数据类型有关,但我不知道如何使它起作用。
我认为 Db2 的任何系列都不支持带有 IN
谓词的数组..
通常需要的是单独的参数
SELECT distinct object_id AS oid
FROM myschema.package p
INNER JOIN myschema.package_item pi ON p.machine_id = pi.machine_id
AND p.package_id = pi.package_id
INNER JOIN main_schema.item i ON i.item_id = pi.id_articulo
WHERE p.package_status_id = 5 AND p.machine_id IN (:machineId1
,:machineId2
,:machineId3
,:machineId4
)
这当然要求您提前知道需要多少个值,或者至少知道某个最大数量。 (您始终可以加载任何剩余参数中的最后一个值。)
另一种选择是传递分隔字符串,该字符串被分割成单独的值。像这样(假设一个逗号分隔列表)
SELECT distinct object_id AS oid
FROM myschema.package p
INNER JOIN myschema.package_item pi ON p.machine_id = pi.machine_id
AND p.package_id = pi.package_id
INNER JOIN main_schema.item i ON i.item_id = pi.id_articulo
WHERE p.package_status_id = 5 AND p.machine_id IN (select int(element)
from table (systools.split(:machineIds, ' '))
)
systools.split() 可能特定于 IBM i 的 Db2,其他平台可能在不同的架构中有它。
如果不出意外,您可以编写自己的用户定义函数 (UDF) 来进行拆分。
对于 LUW 的 Db2:
... IN
(
SELECT TOK
FROM XMLTABLE
(
'for $id in tokenize($s, ",") return <i>{string($id)}</i>'
PASSING CAST (:machineIdsParam AS VARCHAR (100)) AS "s"
COLUMNS
TOK INT PATH '.'
)
)
您为 :machineIdsParam
参数传递了类似“1,2,3”的字符串。即:以逗号分隔的 int 值。