Tsql 带有时态表的计算列

Tsql 带有时态表的计算列,tsql,sql-server-2016,temporal-tables,Tsql,Sql Server 2016,Temporal Tables,我的理解是,不可能在基表具有基于UDF的计算列的情况下设置时态表。但是,我看到有人建议,如果您遵循特定的流程,这应该是可能的: 建议的步骤如下: 首先关闭系统版本控制 然后将计算列添加到基表中 验证结果计算列的“类型” 将具有适当静态类型的列添加到历史记录表中 重新启用系统版本控制 可能这个解决方案只在Azure中有效。我用SQL标准测试了它,使用了一个表,该表有一个datetime类型的UDF计算列,但没有成功。有没有人能够让这个工作,如果有,请分享一个简单的TSQL例子 Tnx同样的情

我的理解是,不可能在基表具有基于UDF的计算列的情况下设置时态表。但是,我看到有人建议,如果您遵循特定的流程,这应该是可能的:

建议的步骤如下:

  • 首先关闭系统版本控制
  • 然后将计算列添加到基表中
  • 验证结果计算列的“类型”
  • 将具有适当静态类型的列添加到历史记录表中
  • 重新启用系统版本控制
可能这个解决方案只在Azure中有效。我用SQL标准测试了它,使用了一个表,该表有一个datetime类型的UDF计算列,但没有成功。有没有人能够让这个工作,如果有,请分享一个简单的TSQL例子


Tnx

同样的情况也适用于Azure和非Azure环境

您必须在同一数据库上创建函数-->
tempdb
。在tempdb上创建函数,它就会工作。但它将在重新启动SQL Server时被释放。具有函数的计算列受数据库模型的限制

您提到的解决方案适用于具有
行版本控制功能的表。但函数的规则是一样的

例如:

    -- have to use tempdb
    use tempdb
    go

    -- UDF
    create function [dbo].ReturnSeven() 
    returns int
    with schemabinding
    begin
        return 7
    end

    -- table
    if object_id('tempdb..#TmpSevenTable') is not null drop table #TmpSevenTable
    create table #TmpSevenTable (
        pk int not null unique, 
        seven as dbo.ReturnSeven() persisted, 
        mpl_seven as pk * dbo.ReturnSeven() persisted)

    insert into #TmpSevenTable (pk) select 1
    insert into #TmpSevenTable (pk) select 3

    -- look at computed columns
    select * from #TmpSevenTable

这是可行的,但UDF必须是有计划的

有一个例子:

CREATE FUNCTION [dbo].[VitalyUTCtoDate] (@UTCDate DATETIME2)
RETURNS DATETIME2 WITH SCHEMABINDING AS  
BEGIN 
    RETURN CASE WHEN @UTCDate < '9999-01-01' THEN DATEADD(HOUR, DATEDIFF(HOUR, GETUTCDATE(), GETDATE()), @UTCDate) ELSE NULL END;
END
GO

CREATE TABLE [dbo].[VitalyTest](
     [ID] [bigint] IDENTITY(1,1) NOT NULL 
    ,[Name] NVARCHAR(255) NOT NULL
    ,[Value] INT NULL
    ,[ValidFrom] DATETIME2 (2) GENERATED ALWAYS AS ROW START HIDDEN 
    ,[ValidTo] DATETIME2 (2) GENERATED ALWAYS AS ROW END HIDDEN

    ,[WhenCreated] AS dbo.VitalyUTCtoDate(ValidFrom)

    ,CONSTRAINT [PK_VitalyTest] PRIMARY KEY CLUSTERED ([ID] 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 (ValidFrom, ValidTo)
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = [dbo].[VitalyTestHistory]))
GO
创建函数[dbo].[VitalyUTCtoDate](@UTCDate-DATETIME2)
返回DATETIME2,SCHEMABINDING为
开始
当@UTCDate<'9999-01-01'然后DATEADD(HOUR,DATEDIFF(HOUR,GETUTCDATE(),GETDATE()),@UTCDate)或NULL END时返回案例;
终止
去
创建表[dbo]。[VitalyTest](
[ID][bigint]标识(1,1)不为空
,[Name]NVARCHAR(255)不为空
,[Value]INT NULL
,[ValidFrom]DATETIME2(2)始终作为行开始隐藏生成
,[ValidTo]DATETIME2(2)始终作为行结束隐藏生成
,[当创建时]为数据生命期(有效期自)
,约束[PK_VitalyTest]主键群集([ID]ASC)
在[主]上打开(PAD\u INDEX=OFF,STATISTICS\u norecocomputer=OFF,IGNORE\u DUP\u KEY=OFF,ALLOW\u ROW\u LOCKS=ON,ALLOW\u PAGE\u LOCKS=ON)
,系统时间周期(有效期从,有效期到)
)
使用(系统版本控制=打开(历史记录\u表=[dbo].[VitalyTestHistory]))
去

我不确定我是否明白。为了能够在具有计算列的表上设置时态表,您是否建议我首先需要将计算列所基于的函数添加到tempDB?为了澄清,基于我的表和历史记录表不在TempDB中。我认为不可能在计算列的声明中使用tempDB中的函数。因此,我不明白你提出的解决方案会如何运作。您能给我一个TSQL示例吗?谢谢,但您所描述的是临时表,而不是临时表