Kusto has_any()报错:无法将参数2转为标量常量的排查求助
Sentinel工作簿has_any函数报错原因及解决
问题场景
在Sentinel工作簿中尝试用has_any匹配用户输入的逗号分隔IP列表时,使用BadIPList变量会报错has_any(): failed to cast argument 2 to scalar constant,但直接定义的BadIPList2可正常运行,且通过gettype和getschema检测两者类型一致。
测试代码:
let StartTime = "2022-08-07"; let TimeOffset = 4d; let BadIPList = '10.1.1.100,10.1.1.102,10.1.1.110,10.1.1.120'; let BadIPlist2 = dynamic(['10.1.1.100','10.1.1.102','10.1.1.110','10.1.1.120']); DeviceNetworkEvents | extend BadIPList=todynamic(split(BadIPList,",")) | where TimeGenerated between (startofday(todatetime(StartTime)) .. endofday(todatetime(StartTime) + TimeOffset)) //next line errors //| where RemoteIP has_any(BadIPList) //next line works | where RemoteIP has_any(BadIPlist2) | project RemoteIP, BadIPList, BadIPlist2 | take 10 //verify variable types | extend ipType = gettype(BadIPList), ipType2 = gettype(BadIPlist2) | getschema
问题原因
has_any函数的第二个参数要求是标量常量数组(查询执行前就确定的固定数组),而你通过extend生成的BadIPList是表的行级列数据——它是在表扩展阶段为每行生成的动态值,不属于查询级的标量常量。虽然类型都显示为dynamic,但两者作用域和生命周期完全不同:
BadIPList2是let语句定义的标量变量,属于查询级常量,has_any可直接识别;- 用
extend生成的BadIPList是表列,仅存在于表的每行数据中,has_any在过滤阶段无法引用行级列作为匹配列表。
解决方法
将字符串转数组的操作提前到let变量定义阶段,直接生成标量常量数组,has_any即可正常识别:
修改后的代码:
let StartTime = "2022-08-07"; let TimeOffset = 4d; let BadIPList = '10.1.1.100,10.1.1.102,10.1.1.110,10.1.1.120'; // 提前在let阶段将字符串转为动态数组,生成标量常量 let ParsedBadIPList = split(BadIPList, ",") | array_concat(); let BadIPlist2 = dynamic(['10.1.1.100','10.1.1.102','10.1.1.110','10.1.1.120']); DeviceNetworkEvents | where TimeGenerated between (startofday(todatetime(StartTime)) .. endofday(todatetime(StartTime) + TimeOffset)) // 现在可以正常使用ParsedBadIPList | where RemoteIP has_any(ParsedBadIPList) | project RemoteIP, ParsedBadIPList, BadIPlist2 | take 10
内容的提问来源于stack exchange,提问作者rick l
相关产品推荐
相关产品推荐

