适用于:✅Azure 数据资源管理器
.update table
命令通过原子删除和追加记录在指定表中执行数据更新。
有两个选项可用于追加记录:
- 根据提供的查询引入记录。 使用 AppendIdentifier 记录查询。
- 移动包含要从另一个表追加到目标表的记录的盘区。 有关详细信息,请参阅 使用移动盘区进行更新。
警告
此命令不可恢复。
权限
你必须至少具有表管理员权限才能运行此命令。
语法
详细了解语法约定。
使用 append
和 delete
:
.update [async] table TableName delete DeleteIdentifier append AppendIdentifier [with ( propertyName = propertyValue )] <|
let DeleteIdentifier = DeletePredicate;
let AppendIdentifier = AppendPredicate;
使用 move extents
和 delete
:
.update [async] table TableName delete DeleteIdentifier move SourceTableName [with ( *propertyName = propertyValue )] <|
let DeleteIdentifier = DeletePredicate;
参数
客户 | 类型 | 必需 | 说明 |
---|---|---|---|
async | string |
如果指定了此项,则指示此命令以异步模式运行。 | |
TableName | string |
✔️ | 要更新的表的名称。 |
DeleteIdentifier | string |
✔️ | 用于指定应用于更新表的删除谓词的标识符名称。 |
DeletePredicate | string |
✔️ | 其结果将用作要删除的数据的查询的文本。 该谓词具有与软删除谓词相同的限制。 |
AppendIdentifier | string |
用于指定应用于更新表的追加谓词的标识符名称。 如果使用基于查询引入的更新,则为必需。 | |
AppendPredicate | string |
其结果将用作要追加的数据的查询的文本。 如果使用基于查询引入的更新,则为必需。 | |
SourceTableName | string |
要从中移动盘区的表的名称。 必须是当前数据库中的本地表。 如果使用 移动盘区进行更新,则为必需。 |
重要
- 删除谓词和追加谓词都不能使用远程实体、跨数据库和跨群集实体。 谓词不能引用外部表或使用
externaldata
运算符。 - 追加和删除查询应生成确定性结果。 非确定性查询可能会导致意外结果。 当且仅当返回相同的数据(如果多次执行)时,查询是确定性的。
- 查询可能会在
update
执行中多次执行。 如果中间查询结果不一致,更新命令可能会生成意外结果。 - 删除和追加谓词基于表的相同快照,因此它们不能相互依赖。 换句话说,追加谓词在删除 前 对源表的快照执行,反之亦然 - 删除谓词在追加 之前 对源表的快照执行。
支持的属性
客户 | 类型 | 说明 |
---|---|---|
whatif |
bool | 如果 true 返回在每个分片中追加/删除的记录数,而不追加/删除任何记录。 默认为 false 。 |
distributed |
bool | 如果为 true ,则此命令将以并行方式从执行查询的所有节点引入。 此选项仅适用于基于从查询引入的更新。 默认值为 false 。 请参阅性能提示。 |
extentTagsToMove |
字符串 | 使用移动盘区进行更新时,可选 盘区标记 仅筛选特定盘区。 标记以数组的形式提供,格式与 引入属性的格式相同。 请参阅 使用移动盘区更新中的示例。 |
重要
建议先在whatif
模式下运行,然后再执行更新以在删除或追加数据之前验证谓词。
返回
该命令的结果是表,其中每个记录表示使用新数据创建的或删除了记录的盘区。
客户 | 类型 | 说明 |
---|---|---|
表 | string |
在其中创建或删除盘区的表。 |
操作 | string |
创建或删除,具体取决于对盘区执行的操作。 |
ExtentId | guid |
由命令创建或删除的盘区的唯一标识符。 |
RowCount | long |
命令在指定区中创建或删除的行数。 |
使用移动盘区进行更新
使用此选项时,要追加到目标表的记录将使用移动盘区从提供的 SourceTableName 移动。 如果命令属性中指定了 extentTagsToMove,则更新将从表中移动所有盘区,或者仅移动与提供的 extentTagsToMove 匹配的盘区。 源表必须是当前数据库中的本地表,并且必须与目标表具有相同的架构。
当要追加的记录已引入到数据库中的临时表时,移动盘区选项非常有用,应替换目标表中的现有记录。 在这种情况下,使用移动盘区选项比从查询引入更有效,因为此选项不需要重新引入记录。 请参阅 使用移动盘区从临时表更新行中的示例。
在.update table
视图和具体化视图之间进行选择
在某些情况下,可以使用.update table
命令或具体化视图在表中实现相同的目标。 例如,具体化视图可用于保留每个记录的最新版本,或者更新可用于在新版本可用时更新记录。
使用以下准则确定要使用的方法:
- 如果具体化视图不支持更新模式,请使用更新命令。
- 如果源表具有较高的引入量,但只有少数更新,则使用更新命令的性能可能更高,并且消耗的缓存或存储也比具体化视图少。 这是因为具体化视图需要重新处理所有引入的数据,这比根据追加或删除谓词标识要更新的各个记录效率低。
- 具体化视图是一种完全托管的解决方案。 具体化视图定义一次,具体化由系统在后台发生。 更新命令需要协调的过程(例如,Azure 数据工厂、逻辑应用等),每次有更新时显式执行更新命令。 如果具体化视图适用于你的用例,则使用具体化视图需要的管理和维护更少。
性能提示
- 数据引入是一项占用大量资源的操作,可能会影响群集上的并发活动(包括正在运行的查询)。 建议避免以下资源密集型操作:一次性运行多个
.update
命令,并大量使用 distributed 属性。 - 将每次操作的追加数据限制在 1 GB 以下。 如有必要,请使用多个更新命令。
-
distributed
仅当查询生成的数据量较大、超过 1 GB 且不需要序列化时,才会将标志设置为true
:多个节点随后可以并行生成输出。 如果查询结果较小,请不要使用此标志,因为可能会不必要地生成很多小数据分片。
示例
对于这些示例,我们将使用下表:
.set-or-replace Employees <|
range i from 1 to 100 step 1
| project Id=i
| extend Code = tostring(dynamic(["Customer", "Employee"])[Id %2])
| extend Color = tostring(dynamic(["Red", "Blue", "Gray"])[Id %3])
此命令创建包含 100 条记录的表,其开头为:
ID | Code | Color |
---|---|---|
1 | 员工 | 蓝色 |
2 | 客户 | 灰色 |
3 | 员工 | Red |
4 | 客户 | 蓝色 |
5 | 员工 | 灰色 |
6 | 客户 | Red |
6 | 员工 | 蓝色 |
更新一行上的单个列
以下示例更新了单个行上的单个列:
.update table Employees delete D append A with(whatif=true) <|
let D = Employees
| where Id==3;
let A = Employees
| where Id==3
| extend Color="Orange";
请注意,whatif
设置为 true。 在此查询后,表保持不变,但命令会返回其中一行被删除的盘区和包含一行的新盘区。
以下命令实际执行更新:
.update table Employees delete D append A <|
let D = Employees
| where Id==3;
let A = Employees
| where Id==3
| extend Color="Orange";
更新多行上的单个列
以下示例将那些具有“blue”值的行中的一个单独列 Color
更新为值“Green”。
.update table Employees delete D append A <|
let D = Employees
| where Code=="Employee"
| where Color=="Blue";
let A = D
| extend Color="Green";
在这里,我们在追加谓词的定义中重用了删除标识符。
更新多行上的多个列
以下示例更新了颜色为灰色的所有行中的多个列。
.update table Employees delete D append A <|
let D = Employees
| where Color=="Gray";
let A = D
| extend Code=strcat("ex-", Code)
| extend Color="";
使用另一个表更新行(引用值)
在此示例中,第一步是创建以下映射表:
.set-or-replace ColorMapping <|
datatable(OldColor:string, NewColor:string)[
"Red", "Pink",
"Blue", "Purple",
"Gray", "LightGray",
"Orange", "Yellow",
"Green", "AppleGreen"
]
然后,此映射表用于更新原始表中的某些颜色:
.update table Employees delete D append A <|
let D = Employees
| where Code=="Customer";
let A = D
| lookup ColorMapping on $left.Color==$right.OldColor
| project Id, Code, Color=NewColor
使用数据表更新行
有时,要更新的值已知未存储在表中,并且数据表运算符可能会有所帮助:
.update table Employees delete D append A <|
let A = datatable(Id:long, Code:string, Color:string)[
1, "Customer", "Purple",
2, "Customer", "Magenta",
3, "Customer", "Turquoise",
];
let D = Employees
| join kind=leftsemi A on Id
| where true;
使用移动盘区更新临时表中的行
一种常用模式是在更新主表之前先在临时表中登陆数据。
第一个命令创建临时表:
.set-or-replace MyStagingTable <|
range i from 70 to 130 step 5
| project Id=i
| extend Code = tostring(dynamic(["Customer", "Employee"])[Id %2])
| extend Color = tostring(dynamic(["Red", "Blue", "Gray"])[Id %3])
下一个命令通过将所有盘区从临时表移动到主表来更新主表,其中包含临时表中的数据:
.update table Employees delete D move MyStagingTable <|
let D = Employees
| join kind=leftsemi MyStagingTable on Id
| where true;
临时表中的一些记录不存在于主表中(即已Id>100
),但仍插入在主表中(更新插入行为)。 由于该命令使用移动盘区,因此更新后 MyStagingTable 将为空。
使用具有盘区标记的移动盘区从临时表进行更新
在此示例中,临时表中的盘区包括盘区标记,我们仅对基于标记子集进行更新感兴趣:
.set-or-replace MyStagingTable with(tags='["drop-by:tag1"]')<|
range i from 70 to 100 step 5
| project Id=i
| extend Code = tostring(dynamic(["Customer", "Employee"])[Id %2])
| extend Color = tostring(dynamic(["Red", "Blue", "Gray"])[Id %3])
.set-or-replace MyStagingTable with(tags='["drop-by:tag2"]')<|
range i from 100 to 150 step 5
| project Id=i
| extend Code = tostring(dynamic(["Customer", "Employee"])[Id %2])
| extend Color = tostring(dynamic(["Red", "Blue", "Gray"])[Id %3])
以下命令使用暂存表中第一个引入(“drop-by:tag1”)中的数据更新主表。 如果只想删除基于此标记的记录,则删除部件还必须筛选盘区标记。 对于删除查询,将考虑整个 MyStagingTable,而不仅仅是使用“drop-by:tag1”的盘区中的记录,因此必须将筛选器显式添加到删除查询。
.update table Employees delete D move MyStagingTable with (extentTagsToMove='["drop-by:tag1"]') <|
let D = Employees | where Id in (MyStagingTable | where extent_tags() has "drop-by:tag1" | project Id);
在命令结束时,MyStagingTable 仅包含第二次引入(“drop-by:tag2”)中的记录,因为命令移动盘区时 drop-by:tag1
。
复合键
第一个命令使用复合键创建表:
.set-or-replace VersionedArticle <|
datatable(ArticleId:string, Version:int, Detail:string)[
"A", 1, "Early version",
"B", 1, "News about mobiles",
"C", 1, "Opinion article",
"B", 2, "Revision about brand X",
"B", 3, "Revision about brand Y",
"C", 2, "Fact check"
]
下一个命令使用扩展的语法更新特定记录:
.update table VersionedArticle delete D append A <|
let D = VersionedArticle
| where ArticleId=="B"
| where Version==3;
let A = VersionedArticle
| where ArticleId=="B"
| where Version==3
| extend Detail = "Revision about brand Z";