如何从不同的数据库复制或更新表索引和约束?
Posted
技术标签:
【中文标题】如何从不同的数据库复制或更新表索引和约束?【英文标题】:How to copy or update table indexes and constraints from different database? 【发布时间】:2019-10-03 09:17:56 【问题描述】:我们有一个生产 Oracle 11g 数据库,该数据库是由试图集成到内部 Web 应用程序的开发人员删除的表。他说他忘记了他已连接到生产数据库并运行他的命令php artisan migrate:fresh
,我搜索了它,它会删除所有表并重新创建它。
然后他尝试使用 flashback 命令恢复所有表。一切都恢复了,但索引、键和约束被重命名了。
是否可以将我们备份数据库的表结构(索引、键、约束)复制/更新到受影响的数据库?
【问题讨论】:
【参考方案1】:我认为没有直接的方法来获得所需的约束和索引名称,但是你可以通过一些手动工作来实现它,如下所示。
首先,您可以使用以下命令更改约束名称:
alter table <table_name> rename constraint <constarint_name> to <new_constarint_name>;
同样的方法,你可以使用以下命令更改索引名称:
ALTER INDEX <index_name> RENAME TO <new_index_name>;
在您的情况下,您需要某种方法将错误(约束/索引)名称与正确名称联系起来。然后用正确的名称重命名约束/索引。要实现它,您可以尝试以下步骤。 (我给出了约束的例子,你可以为索引实现同样的效果)
第 1 步使用以下查询从生产数据库获取约束名称及其数据,并使用该数据在备份数据库中创建一个表。 (您可以使用SQL Loader
或External table
。)将此表命名为PROD_DB_CONS
SELECT
C.TABLE_NAME,
C.CONSTRAINT_NAME,
C.CONSTRAINT_TYPE,
LISTAGG(CC.COLUMN_NAME, ',') WITHIN GROUP(
ORDER BY
COLUMN_NAME
) CONS_COLUMNS
FROM
USER_CONSTRAINTS C
JOIN USER_CONS_COLUMNS CC ON ( C.CONSTRAINT_NAME = CC.CONSTRAINT_NAME )
GROUP BY
C.TABLE_NAME,
C.CONSTRAINT_NAME,
C.CONSTRAINT_TYPE;
第 2 步
使用以下查询在备份数据库中创建相同类型的表:
CREATE TABLE BACKUP_DB_CONS AS
SELECT
C.TABLE_NAME,
C.CONSTRAINT_NAME,
C.CONSTRAINT_TYPE,
LISTAGG(CC.COLUMN_NAME, ',') WITHIN GROUP(
ORDER BY
COLUMN_NAME
) CONS_COLUMNS
FROM
USER_CONSTRAINTS C
JOIN USER_CONS_COLUMNS CC ON ( C.CONSTRAINT_NAME = CC.CONSTRAINT_NAME )
GROUP BY
C.TABLE_NAME,
C.CONSTRAINT_NAME,
C.CONSTRAINT_TYPE;
第 3 步
在Backup DB中执行以下查询,将生成一系列命令来更改生产数据库的所有约束的名称
SELECT
'ALTER TABLE '
|| B.TABLE_NAME
|| ' RENAME CONSTRAINT '
|| P.CONSTRAINT_NAME
|| ' TO '
|| B.CONSTRAINT_NAME
|| ';'
FROM
BACKUP_DB_CONS B
JOIN PROD_DB_CONS P ON ( B.TABLE_NAME = P.TABLE_NAME
AND B.CONS_COLUMNS = P.CONS_COLUMNS );
第 4 步
复制所有命令并在生产数据库中执行所有命令。
干杯!!
【讨论】:
谢谢你。对于Step 3,查询输出已经具有相同constraint_name、正确名称的记录。我想查询由于丢弃而更改了 contraint_names 的记录。对于我的表,它们以 BIN$ 开头。我做了一些更改,但不确定它是否正确。 ``` 这是我更新的代码。你能检查一下'SELECT'ALTER TABLE'|| B.TABLE_NAME || '重命名约束' || P.CONSTRAINT_NAME || '到' || B.CONSTRAINT_NAME || ';'从 BACKUP_DB_CONS B JOIN PROD_DB_CONS P ON(B.TABLE_NAME = P.TABLE_NAME AND B.CONSTRAINT_TYPE = P.CONSTRAINT_TYPE AND B.CONS_COLUMNS = P.CONS_COLUMNS); ` 试试这个:SELECT 'ALTER TABLE ' || B.TABLE_NAME || ' RENAME CONSTRAINT ' || P.CONSTRAINT_NAME || ' TO ' || B.CONSTRAINT_NAME || ';' FROM BACKUP_DB_CONS B JOIN PROD_DB_CONS P ON ( B.TABLE_NAME = P.TABLE_NAME AND B.CONSTRAINT_TYPE = P.CONSTRAINT_TYPE AND B.CONS_COLUMNS = P.CONS_COLUMNS AND B.CONSTRAINT_NAME <> P.CONSTRAINT_NAME);
非常感谢。对于索引,我应该使用什么表?
USER_INDEXES
和 USER_IND_COLUMNS
以上是关于如何从不同的数据库复制或更新表索引和约束?的主要内容,如果未能解决你的问题,请参考以下文章
冲突部分索引的 Postgres 唯一或排除约束无法更新票证