Groovy SQL 命名列表参数
Groovy SQL named list parameter
我想在 SQL 查询中使用 Map 的键集作为列表参数:
query = "select contentid from content where spaceid = :spaceid and title in (:title)"
sql.eachRow(query, [spaceid: 1234, title: map.keySet().join(',')]) {
rs ->
println rs.contentid
}
我可以使用单个值,但不能使用集合或列表。
这是我到目前为止尝试过的:
map.keySet().join(',')
map.keySet().toListString()
map.keySet().toList()
map.keySet().toString()
地图使用字符串作为键
Map<String, String> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
另外,我没有收到错误。我什么也没打印,就像结果集是空的。
您的方法不会给出预期的结果。
从逻辑上讲,您使用的谓词如
title = 'value1,value2,value3'
这就是为什么你没有异常但也没有数据的原因。
快速搜索提供了一点证据,即在 Groovy SQL 中可以将集合映射到 IN 列表。
请检查 here and here
所以很可能您必须以适当的长度定义 IN 列表并从数组中分配值。
title in (:key1, :key2, :key3)
无论如何这样的东西工作正常:
数据
create table content as
select 1 contentid, 1 spaceid, 'AAA' title from dual union all
select 2 contentid, 1 spaceid, 'BBB' title from dual union all
select 3 contentid, 2 spaceid, 'AAA' title from dual;
Groovy 脚本
map['key1'] = 'AAA'
map['key2'] = 'BBB'
query = "select contentid from content where spaceid = :spaceid and title in (${map.keySet().collect{":$it"}.join(',')})"
println query
map['spaceid'] = 1
sql.eachRow(query, map) {
rs ->
println rs.contentid
}
结果
select contentid from content where spaceid = :spaceid and title in (:key1,:key2)
1
2
关键步骤是使用表达式 map.keySet().collect{":$it"}.join(',')
动态准备具有绑定变量专有名称的 IN 列表
备注
您可能还想检查映射的大小并处理大于 1000 的情况,这是 Oracle 对单个 IN 列表的限制。
它对我稍作调整就奏效了,我将地图添加为第二个参数。
def sql = Sql.newInstance("jdbc:mysql://localhost/databaseName", "userid", "pass")
Map<String,Long> mapProduitEnDelta = new HashMap<>()
mapProduitEnDelta['key1'] = 1
mapProduitEnDelta['key2'] = 2
mapProduitEnDelta['key3'] = 3
produits : sql.rows("""select id, reference from Produit where id IN (${mapProduitEnDelta.keySet().collect{":$it"}.join(',')})""",mapProduitEnDelta),
显示 id 1、2、3 的 3 个产品(列 + 来自产品 table 的值)
我想在 SQL 查询中使用 Map 的键集作为列表参数:
query = "select contentid from content where spaceid = :spaceid and title in (:title)"
sql.eachRow(query, [spaceid: 1234, title: map.keySet().join(',')]) {
rs ->
println rs.contentid
}
我可以使用单个值,但不能使用集合或列表。 这是我到目前为止尝试过的:
map.keySet().join(',')
map.keySet().toListString()
map.keySet().toList()
map.keySet().toString()
地图使用字符串作为键
Map<String, String> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
另外,我没有收到错误。我什么也没打印,就像结果集是空的。
您的方法不会给出预期的结果。
从逻辑上讲,您使用的谓词如
title = 'value1,value2,value3'
这就是为什么你没有异常但也没有数据的原因。
快速搜索提供了一点证据,即在 Groovy SQL 中可以将集合映射到 IN 列表。 请检查 here and here
所以很可能您必须以适当的长度定义 IN 列表并从数组中分配值。
title in (:key1, :key2, :key3)
无论如何这样的东西工作正常:
数据
create table content as
select 1 contentid, 1 spaceid, 'AAA' title from dual union all
select 2 contentid, 1 spaceid, 'BBB' title from dual union all
select 3 contentid, 2 spaceid, 'AAA' title from dual;
Groovy 脚本
map['key1'] = 'AAA'
map['key2'] = 'BBB'
query = "select contentid from content where spaceid = :spaceid and title in (${map.keySet().collect{":$it"}.join(',')})"
println query
map['spaceid'] = 1
sql.eachRow(query, map) {
rs ->
println rs.contentid
}
结果
select contentid from content where spaceid = :spaceid and title in (:key1,:key2)
1
2
关键步骤是使用表达式 map.keySet().collect{":$it"}.join(',')
备注
您可能还想检查映射的大小并处理大于 1000 的情况,这是 Oracle 对单个 IN 列表的限制。
它对我稍作调整就奏效了,我将地图添加为第二个参数。
def sql = Sql.newInstance("jdbc:mysql://localhost/databaseName", "userid", "pass")
Map<String,Long> mapProduitEnDelta = new HashMap<>()
mapProduitEnDelta['key1'] = 1
mapProduitEnDelta['key2'] = 2
mapProduitEnDelta['key3'] = 3
produits : sql.rows("""select id, reference from Produit where id IN (${mapProduitEnDelta.keySet().collect{":$it"}.join(',')})""",mapProduitEnDelta),
显示 id 1、2、3 的 3 个产品(列 + 来自产品 table 的值)