Teradata创建索引后如何保留DBC.TABLESV中表原始建表SQL
Teradata保留表原始建表定义SQL的可行方案
首先明确现象本质:Teradata中DBC.TABLESV视图的requesttext列设计逻辑是存储目标对象最后一次执行成功的DDL语句文本,并不是专门存储初始建表语句的字段。因此建表后只要执行CREATE INDEX、ALTER TABLE等任何DDL操作,该字段都会被最新执行的DDL内容覆盖,不存在系统级参数可以修改这个默认行为。
可落地的解决方案如下:
- 事前备份方案(最稳定可靠)
建表语句执行成功、还未执行任何其他表级DDL操作时,立刻从DBC.TABLESV读取对应表的requesttext值,存入自定义的元数据备份表。
可以提前在业务库下建一张专属元数据备份表,参考结构:
每次建表后立刻执行备份逻辑,后续不管对表加索引、改字段,备份表中存储的原始建表SQL都不会被改动。CREATE TABLE custom_db.tbl_ddl_bak ( db_name VARCHAR(128) NOT NULL, tbl_name VARCHAR(128) NOT NULL, original_create_ddl CLOB NOT NULL, bak_timestamp TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, operator VARCHAR(128) NOT NULL DEFAULT USER ) PRIMARY INDEX (db_name, tbl_name); - 事后回溯方案(依赖日志配置)
如果建表时没做提前备份,且环境已经开启了DBQL数据库查询日志,可以从DBQL日志表中回溯最早的建表语句。日志表会留存所有执行过的SQL历史,不会被后续DDL操作覆盖,参考查询逻辑:
注意:该方案受DBQL日志保留周期限制,如果历史日志已经被系统清理,就无法通过该方式获取原始建表SQL,仅适合临时回溯场景SELECT SqlTextInfo AS original_create_ddl FROM DBC.DBQLSqlTbl sql_tbl INNER JOIN DBC.QryLogV qry_log ON sql_tbl.QueryId = qry_log.QueryId WHERE qry_log.StatementType = 'CREATE TABLE' AND sql_tbl.SqlTextInfo LIKE '%目标表名%' AND qry_log.DefaultDatabase = '目标表所属库名' -- 取最早执行的那条CREATE TABLE记录 QUALIFY ROW_NUMBER() OVER (ORDER BY qry_log.StartTime ASC) = 1; - 动态获取当前完整表定义方案
如果需求不是留存最初执行的建表SQL原文,只是需要可以重建当前表(包含所有已创建的索引、约束、分区规则)的完整DDL,直接执行SHOW TABLE 目标库名.目标表名;命令即可。该命令会实时拼接当前表的所有结构属性返回完整DDL,不会受DBC.TABLESV字段覆盖的影响。
注意:永远不要依赖
DBC.TABLESV的requesttext字段做长期元数据归档,该字段的设计定位就不是存储初始建表语句,只要表有后续DDL操作必然会被覆盖。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

