如何将数组传递给更新语句?

How to pass an array to an update statement?

我想对可变数量的行执行更新。我尝试了以下但它不起作用。

def sernos = issue.getCustomFieldValue (ComponentAccessor.getCustomFieldManager().getCustomFieldObject(10719))
def update = '''update mytable set status = 'reserved' where id in (${sernos})'''
sql.executeUpdate (update)

我从 Postgresql 得到一个错误:

syntax error at $

在我看来,Groovy 没有扩展 GString。 sernos 是一个字符串数组列表。以下代码:

log.warn (sernos.getClass())
log.warn (sernos[0].getClass())

报告:

2020-10-15 12:09:06,926 WARN [runner.ScriptBindingsManager]: class java.util.ArrayList
2020-10-15 12:09:06,926 WARN [runner.ScriptBindingsManager]: class java.lang.String

我也试过这个:

def update = '''update mytable set status = 'reserved' where id in (${Sql.expand(sernos)})'''

但是也不行。

如何将字符串列表传递给 SQL where 条件?

您发送的内容会生成一个具有无效 SQL 语法的查询,类似于

update mytable set status = 'reserved' where id in ([a, b, c, d])

其中 [a, b, c, d] 是列表的 toString() 结果。您需要将其转换为适合 IN 子句的文本:

def inText = sernos.collect{"'$it'"}.join(', ')

//also, you need double quotes (" or """) for GString interpolation
def update = "update mytable set status = 'reserved' where id in ($inText)"
...

这会将 update 设置为类似于

的值
update mytable set status = 'reserved' where id in ('a', 'b', 'c', 'd')

现在,您需要小心 sernos 的内容,因为如果列表中的文本包含单引号,上述内容仍然会产生无效的 SQL 语法。如果这是预期的,你必须逃避他们。

这解决了我的问题:

def sernos = issue.getCustomFieldValue (ComponentAccessor.getCustomFieldManager().getCustomFieldObject(10719))
def questionmarks = sernos.collect {'?'}.join (',')
def update = """update mytable set status = 'reserved' where id in (${questionmarks})"""
sql.executeUpdate (update.toString(), sernos)