简体   繁体   English

Groovy SQL命名列表参数

[英]Groovy SQL named list parameter

I want to use a keyset of a Map as a list parameter in a SQL query: 我想将Map的键集用作SQL查询中的列表参数:

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
}

I can use single values but no Sets or Lists. 我可以使用单个值,但不能使用集合或列表。 This is what I've tried so far: 到目前为止,这是我尝试过的:

map.keySet().join(',')
map.keySet().toListString()
map.keySet().toList()
map.keySet().toString()

The map uses Strings as key 该地图使用字符串作为键

Map<String, String> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);

Also, I don't get an error. 另外,我没有得到任何错误。 I just get nothing printed like have an empty result set. 我什么都没有打印,就像结果集为空。

You appoach will not give the expected result. 您无法达到预期的效果。

Logically you are using a predicate such as 逻辑上,您使用的是谓词,例如

 title = 'value1,value2,value3'

This is the reason why you get no exception but also no data. 这就是为什么您没有例外但也没有数据的原因。

Quick search gives a little evidence, that a mapping of a collectiona to IN list is possible in Groovy SQL. 快速搜索提供了一点证据,表明Groovy SQL中有可能将collectiona映射到IN列表。 Please check here and here 在这里这里检查

So very probably you'll have to define the IN list in a proper length and assign the values from your array. 因此,很有可能您必须以适当的长度定义IN列表,并从数组中分配值。

 title in (:key1, :key2, :key3)

Anyway something like this works fine: 无论如何,这样可以正常工作:

Data 数据

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 Script 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
}

Result 结果

select contentid from content where spaceid = :spaceid and title in (:key1,:key2)
1
2

The key step is to dynamicall prepare the IN list with proper names of teh bind variable using the experssion map.keySet().collect{":$it"}.join(',') 关键步骤是使用expersion map.keySet().collect{":$it"}.join(',')动态地为IN列表准备绑定变量的正确名称map.keySet().collect{":$it"}.join(',')

Note 注意

You may also want to check the size if the map and handle the case where it is greater than 1000, which is an Oracle limitation of a single IN list. 您可能还需要检查映射的大小,并处理大于1000的情况,这是Oracle对单个IN列表的限制。

It has worked for me with a little adaptation, I've added the map as a second argument. 它为我工作了一点点适应,我将地图添加为第二个参数。

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),

Display the 3 products (colums + values from the produit table) of id 1, 2, 3 显示ID为1、2、3的3种产品(列+产品表中的值)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM