2016-09-21 200 views
2

我想重命名具有以'SYS'開頭的默認名稱的許多約束(PK,FK,...等),以便能夠將相同的數據插入到其他數據庫中。如何重命名Oracle上的默認約束?

我發現我改成得到我想要下面的腳本:

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 (....) 

問題是我不知道約束的名稱,他們有一個默認的名字,我只知道他們在哪裏。

可能嗎?

+2

我認爲你運氣不好。有'alter table xyz drop | enable | disable primary key',但'rename'不支持該語法。 –

+0

如果你知道約束列,你可以刪除並重新創建它 - 如果你使用ALTER TABLE SPECIALITE DROP PRIMARY KEY KEEP INDEX;那麼你可以添加一個新的PK而不必重建索引,儘管這樣會保留舊的系統生成的名稱。但是如果你不這樣做 - 而且當你重命名很多時,你可能不會這麼做 - 那麼你必須動態地找到它們,所以你現在擁有的將會更簡單。 –

+0

爲什麼不使用具有表名,約束名稱和其他相關信息的user_cons_columns。 – XING

回答

2

如您所知,您需要運行兩個查詢。

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>; 

這將需要第一個查詢複製約束名稱並將其粘貼到第二,在適當的位置(<old_constr_name>)。

如果這是全部,我不會發表一個答案。但是我記得前一段時間我在AskTom上讀過的東西 - 一種聰明的方法,用SQL * Plus中的COLUMN命令來避免複製和粘貼。 (這也可以在SQL Developer和蟾蜍工作)。事情是這樣的:

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語句中使用。

0

如果您沒有約束名稱,則無法直接進行。但是您可以輕鬆生成該聲明。

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'and其重命名爲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表,也許其他有害表

0

添加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