Let 语句

适用于:✅Azure 数据资源管理器Azure MonitorMicrosoft Sentinel

let 语句用于设置与表达式或函数同名的变量名称,或创建视图

let 语句可用于:

  • 将复杂表达式分解为多个部分,每个部分由变量表示。
  • 定义查询正文外部的常量,以提高可读性。
  • 定义变量一次,即可在查询中多次使用。

例如,如果变量以前在嵌套语句中表示另一个值,则会应用最里面的 let 语句。

若要在单个查询中优化 let 语句的多次使用,请参阅优化使用命名表达式的查询

注意

let 语句将名称绑定到某个计算过程,而不是绑定到该计算过程的计算结果值。 此行为意味着,多次引用同一名称可能会返回不同的值,因为该计算过程已多次参与计算。 如果这不是所需的行为,请使用 toscalar()materialize()

语法:标量表达式或表格表达式

let 名称 = 表达式

重要

let 语句必须后跟一个分号。 let 语句之间或 let 语句与其他查询语句之间不能有空行。

详细了解语法约定

参数

客户 类型​​ 必需 说明
Name string ✔️ 变量名称。 可以使用括号对名称进行转义。 例如 ["Name with spaces"]
Expression string ✔️ 具有标量或表格结果的表达式。 例如,具有标量结果的表达式为 let one=1;,具有表格结果的表达式为 let RecentLog = Logs | where Timestamp > ago(1h)

语法:视图或函数

let 名称 = [view] ([ 参数 ]) { FunctionBody }

重要

let 语句必须后跟一个分号。 let 语句之间或 let 语句与其他查询语句之间不能有空行。

详细了解语法约定

参数

客户 类型​​ 必需 说明
FunctionBody string ✔️ 生成用户定义函数的表达式。
view string 仅与无参数的 let 语句相关。 使用时,let 语句包含在带有 union 运算符的查询中,该运算符具有表/视图的通配符选择。 有关示例,请参阅创建视图或虚拟表
Parameters string 零个或多个逗号分隔表格或标量函数参数。

对于每个表格类型的参数,参数应采用 TableName:TableSchema 格式,其中 TableSchema 是一个采用 ColumnName:ColumnType 格式的逗号分隔列列表或一个通配符 (*)。 如果指定了列,则输入表格参数必须包含这些列。 如果指定了通配符,则输入表格参数可以具有任何架构。 若要引用函数正文中的列,必须指定这些列。 有关示例,请参阅带架构的表格参数带通配符的表格参数

对于每个标量类型的参数,请以 Name: Type 格式提供参数名称和参数类型。 名称可以出现在 FunctionBody 中,并在调用用户定义的函数时绑定到特定值。 唯一支持的类型是 boolstringlongdatetimetimespanrealdynamic 和这些类型的别名。

注意

  • 表格参数必须显示在标量参数之前。
  • 必须用分号分隔任意两个语句。

示例

定义标量值

下面的示例使用标量表达式语句。

let n = 10;  // number
let place = "Dallas";  // string
let cutoff = ago(62d); // datetime 
Events 
| where timestamp > cutoff 
    and city == place 
| take n

以下示例使用 ['name'] 表示法绑定名称 some number,然后在表格表达式语句中使用它。

let ['some number'] = 20;
range y from 0 to ['some number'] step 5

使用标量计算创建用户定义函数

此示例使用带有自变量的 let 语句进行标量计算。 该查询定义了用于将两个数字相乘的函数 MultiplyByN

let MultiplyByN = (val:long, n:long) { val * n };
range x from 1 to 5 step 1 
| extend result = MultiplyByN(x, 5)

输出

x result
1 5
2 10
3 15
4 20
5 25

创建用于剪裁输入的用户定义函数

以下示例删除输入中的前导/尾随空格。

let TrimOnes = (s:string) { trim("1", s) };
range x from 10 to 15 step 1 
| extend result = TrimOnes(tostring(x))

输出

x result
10 0
11
12 2
13 3
14 4
15 5

使用多个 let 语句

此示例定义了两个 let 语句,其中一个语句 (foo2) 使用另一个语句 (foo1)。

let foo1 = (_start:long, _end:long, _step:long) { range x from _start to _end step _step};
let foo2 = (_step:long) { foo1(1, 100, _step)};
foo2(2) | count

输出

result
50

创建视图或虚拟表

此示例演示如何使用 let 语句创建 view 或虚拟表

let Range10 = view () { range MyColumn from 1 to 10 step 1 };
let Range20 = view () { range MyColumn from 1 to 20 step 1 };
search MyColumn == 5

输出

$table MyColumn
Range10 5
Range20 5

使用 materialize 函数

materialize() 函数允许在执行查询时缓存子查询结果。 使用 materialize() 函数时,将缓存数据,任何后续的结果调用都使用缓存数据。

let totalPagesPerDay = PageViews
| summarize by Page, Day = startofday(Timestamp)
| summarize count() by Day;
let materializedScope = PageViews
| summarize by Page, Day = startofday(Timestamp);
let cachedResult = materialize(materializedScope);
cachedResult
| project Page, Day1 = Day
| join kind = inner
(
    cachedResult
    | project Page, Day2 = Day
)
on Page
| where Day2 > Day1
| summarize count() by Day1, Day2
| join kind = inner
    totalPagesPerDay
on $left.Day1 == $right.Day
| project Day1, Day2, Percentage = count_*100.0/count_1

输出

第 1 天 第 2 天 百分比
2016-05-01 00:00:00.0000000 2016-05-02 00:00:00.0000000 34.0645725975255
2016-05-01 00:00:00.0000000 2016-05-03 00:00:00.0000000 16.618368960101
2016-05-02 00:00:00.0000000 2016-05-03 00:00:00.0000000 14.6291376489636

使用嵌套的 let 语句

允许使用嵌套的 let 语句,包括在用户定义函数表达式中。 let 语句和自变量适用于函数主体的当前作用域和内部作用域。

let start_time = ago(5h); 
let end_time = start_time + 2h; 
T | where Time > start_time and Time < end_time | ...

带架构的表格参数

以下示例指定表参数 T 必须有一个类型为 stringState 列。 表 T 也可以包含其他列,但不能在函数 StateState 中引用这些列,因为未声明这些列。

let StateState=(T: (State: string)) { T | extend s_s=strcat(State, State) };
StormEvents
| invoke StateState()
| project State, s_s

输出

状态 s_s
大西洋南部 ATLANTIC SOUTHATLANTIC SOUTH
佛罗里达州 FLORIDAFLORIDA
佛罗里达州 FLORIDAFLORIDA
佐治亚州 GEORGIAGEORGIA
密西西比州 MISSISSIPPIMISSISSIPPI
... ...

带通配符的表格参数

表参数 T 可以具有任何架构,函数 CountRecordsInTable 将正常工作。

let CountRecordsInTable=(T: (*)) { T | count };
StormEvents | invoke CountRecordsInTable()

输出

计数
59,066