【问题标题】:Alter GENERATED ALWAYS colum into a GENERATED BY DEFAULT identity column - Sql Server将 GENERATED ALWAYS 列更改为 GENERATED BY DEFAULT 标识列 - Sql Server
【发布时间】:2017-09-12 11:35:32
【问题描述】:

我需要将配置为GENERATED ALWAYS的现有表列更改为GENERATED BY DEFAULT

示例表结构

CREATE TABLE [dbo].[Contact](
    [ContactID] [uniqueidentifier] NOT NULL,
    [ContactNumber] [nvarchar](50) NOT NULL,
    [SequenceID] [int] IDENTITY(1,1) NOT NULL,
    [SysStartTime] [datetime2](0) GENERATED ALWAYS AS ROW START NOT NULL,
    [SysEndTime] [datetime2](0) GENERATED ALWAYS AS ROW END NOT NULL,
 CONSTRAINT [PK_Contact] PRIMARY KEY NONCLUSTERED 
(
    [ContactID] ASC
)WITH (PAD_INDEX = OFF, 
       STATISTICS_NORECOMPUTE = OFF, 
       IGNORE_DUP_KEY = OFF, 
       ALLOW_ROW_LOCKS = ON, 
       ALLOW_PAGE_LOCKS = ON) 
   ON [PRIMARY],
PERIOD FOR SYSTEM_TIME ([SysStartTime], [SysEndTime])
) ON [PRIMARY]
WITH
(
    SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[ContactHistory],
                            DATA_CONSISTENCY_CHECK = ON )
)

这是我现在已经拥有的表格我需要更改列 [SysStartTime]GENERATED BY DEFAULTGENERATED ALWAYS

我尝试了以下代码

ALTER TABLE dbo.Contact ALTER column SysStartTime SET GENERATED BY DEFAULT

但是会报错

Msg 156, Level 15, State 1, Line 19 关键字附近的语法不正确 '设置'。

请帮助我。

【问题讨论】:

  • GENERATED BY DEFAULT 在任何地方都不是合法的 T-SQL 语法,并且一列是否为GENERATED ALWAYS 事后无法更改,就像IDENTITY 一样。由于该列用于生成临时表的历史记录,因此甚至不清楚您要做什么。您是否要删除临时表方面?
  • @JeroenMostert - 不,我需要用旧日期播种一些数据。
  • 让我知道这是对我的问题的支持性问题stackoverflow.com/questions/46174372/…我是对的吗?
  • @B.Balamanigandan - 这是您的问题stackoverflow.com/questions/46174372/…
  • @Mastero:那你就不走运了,因为系统版本的时态表显然不支持这一点。当然,您可以随时更改服务器本身的系统时间。如果你走那条路要小心,因为如果你把时间弄得太乱,像域身份验证这样的事情就会停止工作。此外,显然 SQL Server 可能需要一段时间才能赶上更改的时间。在这种情况下,请考虑在 VM 或其他隔离实例中创建数据库。在最早的时间创建表,并且始终向前移动时钟,从不向后移动。

标签: sql-server sql-server-2016 alter-table temporal-database


【解决方案1】:

我知道这是一个老问题,但我偶然发现了一个类似的问题,我找到了一种方法来实现与此处所需的结果等效的最终结果(让记录讲述它们创建时间的正确故事以及正确处理时间查询)。

我所做的是:

  1. 创建了两个表(主表和历史表)
  2. 已加载主表及其数据
  3. 更新了主表中的所有记录而不更改任何数据。这会导致在历史记录表中创建等效记录
  4. 在表中使用ALTER TABLE Contact SET (SYSTEM_VERSIONING = OFF); 禁用系统版本控制
  5. 更新了历史记录表中的 ValidFrom 字段以正确反映实际最初插入记录的日期。 (只有在禁用表的系统版本控制时才能这样做)
  6. 使用ALTER TABLE Contact SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[ContactHistory], DATA_CONSISTENCY_CHECK = ON ))重新启用表中的系统版本控制

这会导致记录相同(ValidFrom/To 字段除外),但允许使用 FOR SYSTEM_TIME AS OF 'YYYY-MM-DD THH:mm:SS.0000000'; 的任何查询正常工作并准确表示请求时的数据。

我在尝试这个时发现的事情:

  • 您不能将现有字段更改为GENERATED ALWAYS AS ROW START/END。它需要从一开始就是这样设置的字段。
  • 您不能将 DATETIMEOFFSET 字段用于期间字段。
  • 无法在主表的周期字段中设置值
  • 如果启用版本控制,则无法操作历史记录表中的数据

其他文档: https://docs.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver15

【讨论】:

    猜你喜欢
    • 2013-05-09
    • 1970-01-01
    • 2021-10-30
    • 2021-02-26
    • 2017-10-13
    • 2018-02-08
    • 2021-11-15
    • 2019-09-25
    • 1970-01-01
    相关资源
    最近更新 更多