2011-04-28 45 views
3

我想在我的數據庫中有一列可以通過兩個列名臨時訪問。有沒有像Oracle中的「列符號鏈接」?

爲什麼?列名被嚴重選擇,我想重構它。因爲我想我的web應用程序,同時更改列名保持穩定,這將是很好的

  1. 有一個(讓我們叫它)符號鏈接名爲better_column_name指向列bad_column_name
  2. 變化的web應用使用better_column_name
  3. 下降的符號鏈接,並better_column_name重命名列

「重構數據庫」建議實際添加第二列,該列在提交時同步以實現此目的。我只是希望Oracle可能有一個更簡單的方法,減少工作量,減少開銷。

+0

爲什麼不只是協調應用程序代碼的發佈以及所需的數據庫更改?在dev/UAT環境中測試更改並促進以受控,協調的方式提供產品。這個問題有點可怕,說實話 – tbone 2011-04-28 19:52:11

+0

爲什麼它很可怕? Web應用程序分佈在多個Web服務器上,將其展開到所有Web服務器需要一些時間(即分鐘)。當然,我可以宣佈一個小維護窗口,一步完成數據庫和Web應用程序的更改。但我不想如果我能避免它。 – 2011-04-29 13:35:51

回答

4

只要你有使用兩個列名的代碼,我沒有看到一種方法來解決你在該表中有兩個(實際)列的事實。

我會用正確的名稱添加新列,然後創建一個觸發器來檢查哪個列已被修改,並相應地更新「其他」列。所以無論更新什麼,數值都與另一列同步。

一旦使用舊列的所有代碼都已遷移,請刪除觸發器並刪除舊列。

編輯

觸發會如此做這樣的事情:

CREATE OR REPLACE TRIGGER ... 
    ... 
    UPDATE OF bad_column_name, better_column_name ON the_table 
    ... 
BEGIN 
    IF UPDATING ('BAD_COLUMN_NAME') THEN 
    :new.better_column_name = :new.bad_column_name 
    END IF; 

    IF UPDATING ('BETTER_COLUMN_NAME') THEN 
    :new.bad_column_name = :new.better_column_name 
    END IF; 
END; 

IF語句控制其變化具有「高優先級」,以防有人在更新兩列的順序同時。

-1

如果你在11g上,你可以看看使用虛擬列。我可能會試圖稍微改變訂單;重新命名實際的列並使用舊的(壞的)名稱創建虛擬的名字,然後可以在閒暇時放棄。當然,您可能會受到限制,並且可能會導致其他對象無效,從而導致此次訂單不適合您。

+0

虛擬列是這樣做的一種方式,但它並非無痛。使用VC作爲舊的,錯誤的列的問題是,它會打破插入/更新該列的所有內容(因爲DML無法分配給虛擬列)。反過來,使用VC作爲新名稱意味着所有必須更新它的代碼必須立即轉出,同時將VC列切換爲實列。嗯.... – APC 2011-04-28 10:27:14

+0

對,沒有想到這方面。很公平。 – 2011-04-28 10:32:57

+0

但是,將VC用作better_column_name而不是old_bad_column_name也具有優點。這意味着應用程序代碼可以轉換到新的列名,同時保持舊的引用不變。 – 2014-06-10 15:19:22

0

您可以爲表格創建一個視圖。並移植您的應用程序以使用該視圖而不是表格。

create table t (bad_name varchar2(10), c2 varchar2(10)); 
create view vt as select bad_name AS good_name, c2 from t; 

insert into vt (good_name, c2) values ('blub', 'blob'); 

select * from t; 
select * from vt; 
+1

這個下降表的聲明會讓他失去他所有的數據:-) – 2011-04-29 06:20:44

+0

你是對的:),我已經編輯我的答案,並刪除下降聲明。 – schurik 2011-04-29 09:21:04

3

重命名錶:

alter table mytable rename to mytable_old; 

創建與原始表名既bad_column_name和better_column_name 指向同一列的圖(當然,所有其他列):

create or replace view mytable as 
    select column1 
    , column2 
    , ... 
    , bad_column_name 
    , bad_column_name better_column_name 
    from mytable_old 
; 

由於這個視圖默認是可更新的(我在這裏假設mytable有一個主鍵),所以可以在vi中插入/更新/刪除如果使用bad_column_name或better_column_name,則無關緊要。

重構後,刪除該視圖和重命名錶和列:

drop view mytable; 
alter table mytable_old rename column bad_column_name to better_column_name; 
alter table mytable_old rename to mytable; 
3

該最佳解決方案是僅在甲骨文11g第2版可用:基於版的界定。這個非常酷的功能允許我們使用特殊的觸發器和視圖來維護不同版本的數據庫表和PL/SQL代碼。 Find out more

本質上這是Oracle的內置實現@AHorseWithNoName's suggestion

相關問題