利用PLSQL导出ORACLE中的索引和主键,外键DDL语句

本文分享了一种在数据库迁移过程中获取表的主键和索引信息创建DDL语句的技巧。通过SQL查询,可以避免DBMS_METADATA.GET_DDL包的长度限制问题,直接生成完整的创建脚本,简化迁移工作。查询涉及USER_IND_COLUMNS, USER_INDEXES和USER_CONSTRAINTS表,并能区分主键、外键和普通索引。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在数据库迁移过程中,如果能够获取到表的主键和索引信息的创建DDL语句,那将大大方便了我们的迁移过程。

当然了,也可以利用如数据泵之类的工具来直接导出对应的信息,但是不必直接获取对应的ddl来的方便。

但是传统的方法采用DBMS_METEDATA.GET_DDL包来获取对应的DDL语句,也受限于DDL语句的长度,如果语句长度太长,则显示不完整。

下面分享一条语句可以直接将对应的DDL语句获取出来。

SELECT
        T.TABLE_NAME                 , --表名
        T.INDEX_NAME                 , --索引名
        I.UNIQUENESS                 , --是否非空
        I.INDEX_TYPE                 , --索引类型
        C.CONSTRAINT_TYPE            , --键类型
        WM_CONCAT(T.COLUMN_NAME) COLS,
        (CASE WHEN C.CONSTRAINT_TYPE = 'P' OR C.CONSTRAINT_TYPE = 'R' THEN --主键和外键创建脚本拼接
                                'ALTER TABLE '
                                || T.TABLE_NAME
                                || ' ADD CONSTRAINT '
                                || T.INDEX_NAME
                                || (CASE WHEN C.CONSTRAINT_TYPE = 'P' THEN ' PRIMARY KEY (' ELSE ' FOREIGN KEY (' END)
                                || WM_CONCAT(T.COLUMN_NAME)
                                || ');' ELSE --索引创建脚本拼接
                                'CREATE '
                                || (CASE                                 WHEN I.UNIQUENESS = 'UNIQUE' THEN I.UNIQUENESS
                                                        || ' ' ELSE CASE WHEN I.INDEX_TYPE = 'NORMAL' THEN '' ELSE I.INDEX_TYPE
                                                                        || ' ' END END)
                                || 'INDEX '
                                || T.INDEX_NAME
                                || ' ON '
                                || T.TABLE_NAME
                                || '('
                                || WM_CONCAT(COLUMN_NAME)
                                || ');' END) SQL_CMD --拼接创建脚本
FROM
        USER_IND_COLUMNS T,
        USER_INDEXES I    ,
        USER_CONSTRAINTS C
WHERE
        T.INDEX_NAME = I.INDEX_NAME
    AND T.INDEX_NAME = C.CONSTRAINT_NAME(+)
--    AND T.TABLE_NAME LIKE 'TB_%'                --自建表规则(只查询自己创建的表【我的建表规则以TB_开头】,排除系统表)
    AND I.INDEX_TYPE != 'FUNCTION-BASED NORMAL' --排除基于函数的索引
GROUP BY
        T.TABLE_NAME,
        T.INDEX_NAME,
        I.UNIQUENESS,
        I.INDEX_TYPE,
        C.CONSTRAINT_TYPE;

要在SQL中复制一个完整的表,包括它的所有属性(如主键索引、默认值其他约束),而不仅仅是数据本身,通常需要比简单的 `CREATE TABLE ... AS SELECT` 更复杂的步骤。这是因为很多数据库管理系统对通过这种方式创建的新表不会自动继承这些额的元数据特征。 下面是一些常用的关系型数据库系统中实现这一点的方法: ### MySQL/MariaDB 对于MySQL或MariaDB而言,最好的做法可能是先导出DDL脚本再导入到目标位置。你可以利用命令行工具mysqldump来获取所需的DDL语句,然后修改其中的对象名称以适应你要新建的目标表名即可。 也可以手动编写一系列SQL指令来做这件事,但这种方法较为繁琐而且容易遗漏某些细节配置项: 1. **查看现有表的建表语句**: ```sql SHOW CREATE TABLE original_table_name; ``` 2. 将返回结果稍加编辑调整为新表的名字后执行之; 3. 最后再插入数据: ```sql INSERT INTO new_table (column_list) SELECT column_list FROM original_table_name; ``` 不过最简单有效的方式还是借助自动化工具来进行这项任务。 ### PostgreSQL PostgreSQL有一个特别有用的函数叫做`pg_get_viewdef()` 视图相关的其他一些辅助函数可以用来得到定义文本,但对于普通的表我们可以直接使用 `\d+ tablename` 来显示详细的表信息,并从那里获得创建该表所必需的所有详细信息。 此还有更为推荐的做法是采用 `pg_dump --table=original_table -s > schema.sql && psql -c "CREATE TABLE new_table" db < schema.sql` 的形式分离并迁移模式结构。 ### Oracle Database Oracle 数据库提供了多种途径来完成这一目的。一种常见的办法就是运用 Data Pump Export (`expdp`) Import (`impdp`) 工具组合。另一种则是基于PL/SQL块内的动态SQL构建法。 ```plsql DECLARE sql_stmt VARCHAR2(4000); BEGIN FOR rec IN ( SELECT DBMS_METADATA.GET_DDL('TABLE', table_name) dml FROM user_tables WHERE table_name = 'ORIGINAL_TABLE_NAME' ) LOOP EXECUTE IMMEDIATE REPLACE(rec.dml, 'CREATE TABLE ', 'CREATE TABLE NEW_TABLE_NAME '); END LOOP; EXECUTE IMMEDIATE 'INSERT /*+ APPEND */ INTO NEW_TABLE_NAME SELECT * FROM ORIGINAL_TABLE_NAME'; END; / ``` 请注意上述例子中的大小写的敏感度取决于各自系统的设定情况。 综上所述,在不同类型的RDBMS里实现精准无误地克隆一张完好的表并非易事,很多时候涉及到特定平台特性的理解应用。如果你经常有这样的需求建议考虑学习熟悉下各主流厂商提供的备份恢复机制以及ETL框架的支持能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值