You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Groovy SQL中读取每行?解决MachineName属性不存在报错

解决Groovy sql.eachRow静态类型检查错误:No such property: MachineName for class: java.lang.Object

这个问题其实是两个点导致的:一是代码里的语法错误,二是Groovy静态类型检查的限制。咱们一步步来解决:

1. 先修复明显的语法错误

你在eachRow方法的参数传递上括号配对出错了,SQL语句和参数Map的位置没放对。正确的eachRow调用格式应该是把SQL字符串作为第一个参数,参数Map作为第二个参数,再跟上处理行的闭包。

2. 解决静态类型检查的限制

当Groovy开启静态类型检查(比如使用@CompileStatic注解)时,闭包里的row对象会被默认推断为Object类型,静态检查器不知道它有MachineName这个属性,所以会抛出"No such property"的错误。针对这个问题,有几种常用的解决方式:

方式一:使用下标访问列

用row["列名"]的方式访问,这种写法能被静态检查器识别,避免属性不存在的错误:

// 修正后的完整代码示例
sql.eachRow('select * from [MACHINES] WHERE UpdateTime > :lastTimeRead', [lastTimeRead: Long.parseLong(lastTimeRead)]) { row ->
    def read = row["MachineName"]
}

方式二:明确指定row的类型

如果你的代码开启了@CompileStatic,可以把闭包里的row类型指定为GroovyResultSet(Groovy对JDBC ResultSet的包装类),这样静态检查器就能识别列属性:

@CompileStatic
def loadMachines(Sql sql, String lastTimeRead) {
    sql.eachRow('select * from [MACHINES] WHERE UpdateTime > :lastTimeRead', [lastTimeRead: Long.parseLong(lastTimeRead)]) { GroovyResultSet row ->
        def read = row.MachineName
    }
}

方式三:使用getAt方法

和下标访问等价,调用row.getAt("MachineName")也能绕过静态检查的限制:

def machineName = row.getAt("MachineName")

方式四:临时关闭静态检查(不推荐,除非必要)

如果只是这一段代码有问题,可以给闭包或者方法加上@SuppressWarnings("GroovyAssignabilityCheck")注解,临时关闭该部分的静态类型检查:

@SuppressWarnings("GroovyAssignabilityCheck")
sql.eachRow('select * from [MACHINES] WHERE UpdateTime > :lastTimeRead', [lastTimeRead: Long.parseLong(lastTimeRead)]) { row ->
    def read = row.MachineName
}

总结

先修正语法错误,再根据是否开启静态类型检查选择对应的列访问方式,就能解决这个错误了。

内容的提问来源于stack exchange,提问作者user9630935

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:42:59