2009-02-23 27 views
9

將列添加到現有表時,Oracle始終將該列放在表的末尾。是否有可能告訴Oracle它應該出現在表中?如果是這樣,怎麼樣?在Oracle中,是否可以將一列插入表中?

+2

「爲什麼訂單很重要?」當然這對有人試圖閱讀這件事很重要。訂單使它更容易理解。 – tdugan 2013-02-12 22:11:44

+0

@tdugan - 有人試圖閱讀的東西可以任何他們想要的方式命令列。 – 2013-02-13 02:56:55

+0

@JeffreyKemp:是的,他們可以每次看到它時都會點一次,一次又一次...... – maaartinus 2014-05-04 04:07:27

回答

1

我不這麼認爲--SQL Server也不允許這些。我總是不得不使用的方法是:

  1. 創建新表,看起來權利(包括附加列
  2. BEGIN TRANSACTION
  3. 選擇舊錶中的所有數據到新的一個
  4. 刪除舊錶
  5. 重命名新表
  6. 提交的事務。

不EXA很漂亮,但完成工作。

2

我通常做的是:

  1. 重命名舊錶。
  2. 按照正確的順序創建具有列的新表。
  3. 爲該新表創建約束。
  4. 填充數據:插入到new_table select * from renamed table。
2

我不認爲如果不將數據保存到臨時表中,刪除表並重新創建它,就不會這樣做。另一方面,這個欄目在哪裏確實不重要。只要您在select語句中指定要檢索的列,您可以根據需要訂購它們。

0

不,不可能通過「ALTER TABLE」語句。但是,您可以創建一個與當前定義相同的新表,儘管名稱不同,但按照您希望的方式按正確順序排列。將數據複製到新表中。放下舊桌子。重命名新表以匹配舊錶名。

湯姆凱特有AskTom這個文章 link text

8

在表中的列的位置應該是不重要的(除非有「頁面大小」來考慮,或任何Oracle使用實際存儲的數據)。對消費者來說更重要的是如何調用結果,即Select語句。

5

將YOUR_ORIGINAL_TABLE重命名爲YOUR_NEW_TABLE;

創建表YOUR_ORIGINAL_TABLE NOLOGGING/*或不可恢復的*/ 作爲 選擇列1,列2,NEW_COLUMN,欄3 從YOUR_NEW_TABLE;

刪除表格YOUR_NEW_TABLE;

選擇* From YOUR_ORIGINAL_TABLE; < < < < <現在您將在表格中間看到新列。

但你爲什麼要這麼做?這似乎不合邏輯。如果列順序非常重要,則不應假定列順序,只使用命名列列表。

2

爲什麼列的順序很重要?你可以隨時在你的select語句中修改它嗎?

在表格末尾添加新列有一個優點。如果有代碼天真地執行「SELECT *」,然後按順序解析這些字段,則不會因末尾添加新列而破壞舊代碼。如果您在表格中間添加新列,則舊代碼可能會被破壞。

在一份工作中,我有一個超級肛門的DBA,他說:「從不做'SELECT *'」。他堅持說你總是寫出具體的領域。

2

請記住,在表格下,表格記錄中的所有數據都粘在一起。將一列添加到表格的末尾[如果它可以爲空或(在更高版本中)不爲空],則表示對錶格的元數據進行更改。 在中間添加一列需要重寫該表中的每條記錄,以便爲該列添加適當的值(或標記)。在某些情況下,這可能意味着記錄在塊上佔用更多空間,並且需要遷移一些記錄。 簡而言之,對於任何實際大小的表而言,這是VAST的IO努力量。

你總是可以創造超過已經在首選順序列的表視圖,並通過該視圖在一個DML語句就像你表

-1

1)好了,所以你不能直接做。我們不需要在發帖後說出同樣的事情,是嗎?

2)好吧,表中列的順序在技術上並不重要。但這不是重點,原來的問題只是問你是否可以完成。不要認爲你知道其他人的要求。也許他們有一個100列的表,當前正在使用「SELECT * ...」在一些怪異的黑客一起查詢,他們只是不想嘗試解開查詢,更不用說用* 100列名替換「*」。或者,也許他們只是關於事物順序的肛門,並且像SQL Developer一樣在瀏覽模式時希望彼此相鄰的領域相鄰。也許他們正在與非技術人員打交道,從邏輯上講,它應該在接近開始的某個地方,不知道要看100列列表的末尾。

沒有比問一個誠實的問題和得到一個答案,說:「你不應該這樣做」更惱人。這是我的工作,不是你的!請不要告訴我如何做我的工作。如果可以,請提供幫助。謝謝!

好的...抱歉的咆哮。現在...在www.orafaq.com上提出了這個解決方法。

首先假設你已經運行:

CREATE TABLE TAB1(COL1 NUMBER);

現在說你想添加一個名爲「col2」的列,但是你希望他們在執行「SELECT * FROM tbl1;」時排序爲「col2」,「col1」。

的建議是運行:

ALTER TABLE TAB1 ADD(COL2 DATE); RENAME tab1 TO tab1_old; CREATE TABLE tab1 AS SELECT 0 AS col1,col1 AS col2 FROM tab1_old;

我發現這是令人難以置信的誤導。首先,你用「零」來填充「col1」,如果你有任何數據,那麼你就會因爲這樣做而失去它。其次,它實際上將「col1」重命名爲「col2」,但沒有提及這一點。所以,這裏是我的榜樣,希望這是一個更清晰一點:

假設您有與下面的語句創建一個表:

CREATE TABLE用戶(如first_name VARCHAR(25),姓氏VARCHAR(25));

現在假設你想在first_name和last_name之間插入middle_name。這裏有一種方法:

ALTER TABLE用戶ADD middle_name varchar(25); RENAME用戶TO users_tmp; CREATE TABLE用戶AS SELECT first_name,middle_name,last_name FROM users_tmp; /*和好的措施... */ DROP TABLE testusers_tmp;

請注意,middle_name將默認爲NULL(由ALTER TABLE語句暗示)。您可以在CREATE TABLE語句中設置不同的默認值,如下所示:

CREATE TABLE users AS SELECT first_name,'some default value'AS middle_name,last_name FROM users_tmp;

如果您添加缺省值爲sysdate的日期字段,但希望所有現有記錄具有其他一些(例如較早的)日期值,此技巧可能會派上用場。

相關問題