.update table 命令

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

.update table 命令通过原子删除和追加记录在指定表中执行数据更新。 有两个选项可用于追加记录:

  • 根据提供的查询引入记录。 使用 AppendIdentifier 记录查询。
  • 移动包含要从另一个表追加到目标表的记录的盘区。 有关详细信息,请参阅 使用移动盘区进行更新

警告

此命令不可恢复。

注意

在作为.update table源的表上运行 命令时,.update table 命令将触发这些更新策略,其中被修改的表是更新策略源。

一条命令最多可以删除 500 万条记录。

权限

你必须至少具有表管理员权限才能运行此命令。

语法

详细了解语法约定

使用 appenddelete

.update [async] table TableName delete DeleteIdentifier append AppendIdentifier [with ( propertyName = propertyValue )] <|
let DeleteIdentifier = DeletePredicate;
let AppendIdentifier = AppendPredicate;

使用 move extentsdelete

.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";