如何在Kusto数据表的每一行调用带多参数的标量函数
在Kusto数据表每行调用自定义函数的解决方案
问题场景
现有一个Kusto函数test_data,设计为接收参数并返回标量输出,尝试在数据表的每一行调用该函数时遇到两类错误:
- 直接用
extend调用时,报错:Semantic error: Tabular expression is not expected in the current context - 用
toscalar包裹调用时,报错:Semantic error: 'toscalar' operator: Failed to resolve table or scalar expression named 'since'
原函数定义:
function test_data(since:datetime) { // 执行一些操作并返回标量结果 let result = <sometable>; let scalar_data = toscalar(result); print(scalar_events); // 此处错误:print返回表格,而非标量 }
原调用代码:
let result_data = datatable(since:datetime) [ datetime(2023-09-20T18:37:14.5162522Z), datetime(2023-09-20T18:37:29.2246502Z), datetime(2023-09-20T18:37:29.2246502Z), datetime(2023-09-20T18:37:29.2246502Z), ]; result_data | extend data = test_data(since);
错误原因
- 函数定义不符合标量要求:原函数最后用
print返回结果,这会生成单列表格,导致函数实际是表格函数,而非标量函数,无法直接在extend中使用。 - 行上下文访问限制:
toscalar的参数是全局表达式,无法访问extend中的行级变量(如since),因此出现变量无法解析的错误。
正确解决方案
方案1:修正为标量函数后直接调用
步骤1:调整函数为真正的标量函数
去掉print,直接返回标量值:
let test_data = (since:datetime) { // 示例操作:查询某表并提取标量结果 let result = <sometable> | where timestamp >= since | count; toscalar(result) // 直接返回标量,无需print };
步骤2:在数据表每行调用标量函数
标量函数可直接通过extend调用,支持访问行级变量:
let result_data = datatable(since:datetime) [ datetime(2023-09-20T18:37:14.5162522Z), datetime(2023-09-20T18:37:29.2246502Z), datetime(2023-09-20T18:37:29.2246502Z), datetime(2023-09-20T18:37:29.2246502Z), ]; result_data | extend data = test_data(since);
方案2:若函数需返回表格(多列结果)
如果函数必须返回表格(比如包含多个字段的结果),使用apply操作符,它可以对数据表的每一行执行表格函数,并将结果合并到原表中:
// 定义返回表格的函数示例 let test_data_table = (since:datetime) { <sometable> | where timestamp >= since | summarize event_count = count(), max_value = max(value) }; let result_data = datatable(since:datetime) [ datetime(2023-09-20T18:37:14.5162522Z), datetime(2023-09-20T18:37:29.2246502Z), ]; result_data | apply test_data_table(since);
关键说明
- 标量函数:返回单个值,可直接在
extend、where等子句中使用,支持访问行级变量。 - 表格函数:返回表格结构,需用
apply操作符在每行调用,apply会将每行参数传入函数,并将结果与原行合并。
内容的提问来源于stack exchange,提问作者kgangadhar
相关产品推荐
相关产品推荐

