【问题标题】:How to rename a default constraint on Oracle?如何重命名 Oracle 上的默认约束?
【发布时间】:2016-09-21 23:06:08
【问题描述】:

我想重命名许多具有以“SYS”开头的默认名称的约束(PK、FK、...等),以便能够在其他数据库中插入相同的数据。

我找到了以下脚本,为了得到我想要的东西而进行了更改:

BEGIN
    FOR cn IN (
        SELECT constraint_name 
        FROM user_constraints 
        WHERE constraint_type = 'P'
        AND table_name = 'SPECIALITE'
    )
    LOOP
        EXECUTE IMMEDIATE 'ALTER TABLE ' || cn.table_name || ' RENAME CONSTRAINT ' || cn.constraint_name  || ' TO PK_' || 'SPECIALITE';
    END LOOP;
END;

这个脚本有效,但对我来说似乎有点复杂,我想知道它是否存在:

ALTER TABLE 'SPECIALITE' RENAME CONSTRANT (....)

问题是我不知道约束的名称,它们有一个默认名称,我只知道它们所在的表。

有可能吗?

【问题讨论】:

  • 我觉得你运气不好。有alter table xyz drop|enable|disable primary key,但是rename不支持语法。
  • 如果你知道约束列,你可以删除并重新创建它 - 如果你 ALTER TABLE SPECIALITE DROP PRIMARY KEY KEEP INDEX; 那么你可以添加一个新的 PK 而不必重建索引,尽管这将保留旧系统- 生成的名称。但是,如果您不这样做 - 并且因为您要重命名许多您可能不这样做 - 那么您无论如何都必须动态找到它们,所以您现在拥有的会更简单。
  • 为什么不使用 user_cons_columns ,它有表名、约束名和其他相关信息。
  • ALTER TABLE SPECIALITE RENAME CONSTRAINT SYS_C002786098 TO PK_SPECIALITE 是命令。您需要知道要重命名的约束的名称。您可以从 USER_CONSTRAINTS 获取您拥有的表的约束名称。即——你的脚本很好。
  • @WilliamRobertson - 不走运;语法是alter table rename constraint ....,它适用于主键和所有其他可以命名的约束。 (not null 约束无法命名,但这是有道理的 - 您不能引用 not null 约束。)

标签: sql oracle plsql


【解决方案1】:

如您所知,您需要运行两个查询。

select constraint_name from user_constraints 
where table_name = <table_name> and constraint_type = 'P';

并且手头有约束名称,

alter table <table_name> rename constraint <old_constr_name> to <new_constr_name>;

这需要从第一个查询中复制约束名称并将其粘贴到第二个查询的适当位置 (&lt;old_constr_name&gt;)。

如果这就是全部,我不会发布答案。但我记得前段时间在 AskTom 上读到的一些内容 - 一种避免复制和粘贴的巧妙方法,使用 SQL*Plus 中的 COLUMN 命令。 (这也可以在 SQL Developer 和 Toad 中使用。)像这样:

column constraint_name new_val c   -- Note: no semicolon - this is SQL*Plus, not SQL

select constraint_name from user_constraints 
where table_name = <table_name> and constraint_type = 'P';

alter table <table_name> rename constraint &c to <new_constr_name>;

如果您需要更改许多 PK 约束名称,这将节省一些工作。 SELECT 查询返回的约束名称保存在 SQL*Plus COLUMN 命令中标记为“c”的“new_val”中,并在 ALTER TABLE 语句中使用。

【讨论】:

    【解决方案2】:

    user_cons_columns 视图添加到您的SQL 中,这样您就可以生成约束名称。这是一个快速而肮脏的例子:

    select 'ALTER TABLE ' || c.table_name || ' RENAME CONSTRAINT ' || c.constraint_name  || ' TO ' || substr(c.constraint_type || '_' || c.table_name || '_' || replace(wm_concat(cc.column_name), ',', '_'), 0, 30) || ';'
    from user_constraints c
    join user_cons_columns cc on c.table_name = cc.table_name and c.constraint_name = cc.constraint_name
    where c.constraint_name like 'SYS%'
    group by c.table_name, c.constraint_name, c.constraint_type;
    

    此 SQL 生成一个可执行脚本,其中包含如下命令:

    ALTER TABLE TABLENAME RENAME CONSTRAINT SYS_xxxxxx TO C_TABLENAME_COLUMN;
    

    请注意,我正在使用未记录的 wm_concat 函数。如果您使用的是 Oracle >= 11g,请考虑改用 listagg

    【讨论】:

      【解决方案3】:

      如果你没有约束名,你不能直接做。但是您可以轻松生成语句。

      select 'ALTER TABLE ' || table_name || ' RENAME CONSTRAINT ' || constraint_name || ' TO PK_' || upper( table_name )
      from user_constraints
      where constraint_type = 'P'
      and constraint_name like 'SYS%';
      

      这个选择会列出所有主键有约束的以'SYS'开头的表,并将其重命名为PK_TABLE_NAME;

      您只需检查所有语句是否适合您并运行它们。

      你也可以像这样使用生成的列

      select 'ALTER TABLE ' || table_name || ' RENAME CONSTRAINT ' || constraint_name || ' TO PK_' || upper( table_name )
      from user_constraints
      where constraint_type = 'P'
      and generated = 'GENERATED NAME';
      

      但你会有 BIN 表,可能还有其他不需要的表

      【讨论】:

        猜你喜欢
        • 2020-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-17
        • 2021-06-18
        • 1970-01-01
        相关资源
        最近更新 更多