sql-server - 删除系统版本化时态表的过程

标签 sql-server tsql

我正在寻找一个过程来删除系统版本控制的时态表,理想情况下不使用动态 SQL。我已经浏览了 Microsoft 文档并想出了如何获取自动生成的历史记录表名称,但我对游标知之甚少,对动态 SQL 知之甚少。

You can't just drop a temporal table .必须先禁用版本控制,这会导致历史表变成普通表。然后,您可以删除时态表及其对应的历史表。

ALTER TABLE [dbo].[TemporalTest] SET ( SYSTEM_VERSIONING = OFF )
GO
DROP TABLE [dbo].[TemporalTest]
GO
DROP TABLE [dbo].[TemporalTestHistory]
GO

我正在使用带有自动生成历史表的时态表,所以我不知道它们的名字。然而,Microsoft docs提供有关如何列出历史表的信息,因此我有一种获取这些名称的方法。

select schema_name(t.schema_id) as temporal_table_schema,
     t.name as temporal_table_name,
    schema_name(h.schema_id) as history_table_schema,
     h.name as history_table_name,
    case when t.history_retention_period = -1 
        then 'INFINITE' 
        else cast(t.history_retention_period as varchar) + ' ' + 
            t.history_retention_period_unit_desc + 'S'
    end as retention_period
from sys.tables t
    left outer join sys.tables h
        on t.history_table_id = h.object_id
where t.temporal_type = 2
order by temporal_table_schema, temporal_table_name

我希望我可以在 DROP 语句中使用子查询,例如DROP TABLE (SELECT '#t') .这会引发语法错误。

我正在寻找一个带有两个参数的存储过程:要删除的表的名称以及如果表中有任何数据(例如,必须 ROWCOUNT=0)是否应该进行删除。任何人都可以帮助或推荐动态 SQL 上的游标,或推荐另一种技术吗?谢谢!

最佳答案

您不能针对数据(如子查询的输出)发出 DDL,也不能将实体名称作为变量传递给语句;您需要动态 SQL。

CREATE PROCEDURE dbo.DropTemporalTable
  @schema sysname = N'dbo',
  @table  sysname
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @sql nvarchar(max) = N'';

  SELECT @sql += N'ALTER TABLE ' + src + N' SET (SYSTEM_VERSIONING = OFF);
    DROP TABLE ' + src  + N';
    DROP TABLE ' + hist + N';'
  FROM
  (
    SELECT src = QUOTENAME(SCHEMA_NAME(t.schema_id))
               + N'.' + QUOTENAME(t.name),
          hist = QUOTENAME(SCHEMA_NAME(h.schema_id))
               + N'.' + QUOTENAME(h.name)
    FROM sys.tables AS t
    INNER JOIN sys.tables AS h
    ON t.history_table_id = h.[object_id]
    WHERE t.temporal_type = 2
      AND t.[schema_id] = SCHEMA_ID(@schema)
      AND t.name = @table
  ) AS x;

  EXEC sys.sp_executesql @sql;
END
GO

关于sql-server - 删除系统版本化时态表的过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55522278/

相关文章:

sql-server - session 如何检测它是否在打开 XACT_ABORT 的情况下运行?

sql-server - 为什么主键顺序很重要?

sql-server - 安装 Microsoft SQL Express 2012 后 FreeTDS 无限期挂起

sql - 存储过程中的值转换

sql-server - 如何在 MSSQL 中将 VARCHAR 转换为 TIMESTAMP?

sql-server - @parameter = @parameter 语法 (SQL Server)

sql - 如果我们在有序集中有重复值,如何解决 LEAD 或 LAG 分析函数中的关系?

sql-server - ALTER VIEW 必须是批处理中唯一的语句

sql-server - SQL Server 中图像列的 MD5 总和

sql-server - 无法在 SQL Server 2008 上绑定(bind)多部分标识符