2009-02-23 47 views
9

Khi thêm cột vào bảng hiện có, Oracle luôn đặt cột ở cuối bảng. Có thể nói cho Oracle biết nó sẽ xuất hiện trong bảng nào không? Nếu vậy, làm thế nào?Trong Oracle, có thể "chèn" một cột vào một bảng không?

+2

"Tại sao đơn đặt hàng lại quan trọng?" tất nhiên điều đó quan trọng đối với ai đó đang cố đọc điều đó. Đặt hàng làm cho nó dễ hiểu hơn. – tdugan

+0

@tdugan - ai đó đang cố gắng đọc điều có thể đặt hàng các cột theo bất kỳ cách nào họ muốn. –

+0

@ JeffreyKemp: Vâng, họ có thể yêu cầu họ mỗi khi họ nhìn vào nó, lặp đi lặp lại .... – maaartinus

Trả lời

1

Tôi không tin như vậy - SQL Server cũng không cho phép điều này. Phương pháp tôi luôn luôn phải sử dụng là:

  1. Tạo bảng mới mà có vẻ đúng (bao gồm thêm cột
  2. Bắt đầu giao dịch
  3. chọn tất cả các dữ liệu từ bảng cũ vào một
  4. Drop bảng cũ mới
  5. Đổi tên bảng
  6. mới Commit giao dịch.

Không exa ctly khá, nhưng được công việc làm.

+1

Máy chủ SQL sẽ cho phép bạn đặt cột vào bảng mà bạn muốn khi bạn sử dụng Trình thiết kế bảng. Điều này có thể được thực hiện ngay cả khi đã có dữ liệu và hàng trong bảng hiện tại (miễn là bạn có cột được đặt thành Nullable hoặc đặt giá trị mặc định) – TheTXI

+0

Đủ công bằng, nhưng ở mặt sau, nó thực thi tập lệnh chính xác này. Thậm chí nếu bạn thêm một cột vào cuối bảng, nó thực hiện điều này, đó là lý do tại sao các sửa đổi bảng thông qua trình thiết kế có thể mất nhiều thời gian để thực thi. – SqlRyan

+1

Bước 2. và 6. là thừa. Tất cả các câu lệnh DDL làm thay đổi lược đồ buộc một giao dịch ngầm tiềm ẩn mới. Bạn không thể có các thay đổi DML nổi bật khi bạn thay đổi cấu trúc. – Khb

2

Những gì tôi thường làm là:

  1. Đổi tên bảng cũ.
  2. Tạo bảng mới với các cột theo đúng thứ tự.
  3. Tạo các ràng buộc cho bảng mới đó.
  4. Điền dữ liệu: Chèn vào new_table select * từ bảng đã đổi tên.
2

Tôi không nghĩ rằng điều này có thể được thực hiện mà không lưu dữ liệu vào bảng tạm thời, thả bảng và tạo lại bảng. Mặt khác, nó thực sự không quan trọng vị trí của cột. Miễn là bạn chỉ định các cột bạn đang truy xuất trong câu lệnh chọn, bạn có thể đặt chúng theo bất kỳ cách nào bạn muốn.

0

Không, không thể thực hiện được thông qua tuyên bố "ALTER TABLE". Tuy nhiên, bạn có thể tạo một bảng mới với định nghĩa tương tự như bảng hiện tại của bạn, mặc dù với một tên khác, với các cột theo đúng thứ tự theo cách bạn muốn. Sao chép dữ liệu vào bảng mới. Thả cái bàn cũ. Đổi tên bảng mới để khớp với tên bảng cũ.

Tom Kyte có một bài viết về vấn đề này trên AskTom link text

8

Vị trí của các cột trong bảng nên không quan trọng (trừ khi có "kích thước trang" để xem xét, hoặc bất cứ điều gì Oracle sử dụng để thực sự lưu trữ dữ liệu). Điều quan trọng hơn đối với người tiêu dùng là cách kết quả được gọi, tức là câu lệnh Select.

5

đổi tên YOUR_ORIGINAL_TABLE thành YOUR_NEW_TABLE;

tạo bảng YOUR_ORIGINAL_TABLE nologging/* hoặc không thể phục hồi */ như chọn COLUMN1, column2, NEW_COLUMN, cột3 từ YOUR_NEW_TABLE;

Thả bảng YOUR_NEW_TABLE;

Chọn * Từ YOUR_ORIGINAL_TABLE; < < < < < bây giờ bạn sẽ thấy cột mới ở giữa bảng.

Nhưng tại sao bạn muốn làm điều đó?Nó có vẻ phi logic. Bạn không bao giờ nên giả định thứ tự cột và chỉ sử dụng danh sách cột được đặt tên nếu thứ tự cột là quan trọng.

+1

Của nó nhiều hơn một thẩm mỹ điều bất cứ điều gì khác. Dữ liệu được lưu trữ đến từ một nguồn bên ngoài (XML), trong đó chúng được thêm vào một trường ở giữa dữ liệu của chúng. Vì vậy, nó chỉ là loại sucks rằng bảng của chúng tôi bây giờ theo thứ tự như XML cho tất cả các cột nhưng một. – larf311

2

Tại sao thứ tự của các cột lại quan trọng? Bạn luôn có thể thay đổi nó trong câu lệnh chọn của bạn?

Có lợi thế khi thêm cột mới ở cuối bảng. Nếu có mã ngây thơ làm một "SELECT *" và sau đó phân tích cú pháp các trường theo thứ tự, bạn sẽ không phá vỡ mã cũ bằng cách thêm các cột mới ở cuối. Nếu bạn thêm các cột mới ở giữa bảng, thì mã cũ có thể bị hỏng.

Tại một công việc, tôi có một DBA siêu hậu môn về "Never do 'SELECT *'". Ông nhấn mạnh rằng bạn luôn viết ra những lĩnh vực cụ thể.

+1

Và dba của bạn là abosolutely chính xác để làm như vậy. Chọn * có thể phá vỡ một số lượng lớn thứ và nếu bạn có bất kỳ phép nối nào trả về nhiều trường dữ liệu hơn mức bạn cần (các trường kết nối được nhân đôi) và do đó lãng phí cơ sở dữ liệu và tài nguyên mạng quý giá. – HLGEM

2

Hãy nhớ rằng, dưới các bảng, tất cả dữ liệu trong các bản ghi bảng được dán lại với nhau. Thêm một cột vào cuối một bảng [nếu nó là nullable hoặc (trong các phiên bản sau) không null với một mặc định] chỉ có nghĩa là một sự thay đổi cho siêu dữ liệu của bảng. Việc thêm một cột ở giữa sẽ yêu cầu viết lại mọi bản ghi trong bảng đó để thêm giá trị thích hợp (hoặc điểm đánh dấu) cho cột đó. Trong một số trường hợp, điều đó có nghĩa là các bản ghi chiếm nhiều chỗ hơn trên các khối và một số bản ghi cần được di chuyển. Tóm lại, đó là số lượng VAST của nỗ lực IO cho một bảng có kích thước thực bất kỳ.

Bạn luôn có thể tạo ra một cái nhìn trên bảng có các cột theo thứ tự ưu tiên và sử dụng quan điểm đó trong một tuyên bố DML cũng giống như bạn sẽ bảng

-1

1) Ok, do đó bạn không thể làm điều đó trực tiếp . Chúng tôi không cần đăng bài sau khi đăng bài nói cùng một điều, phải không?

2) Ok vì vậy thứ tự các cột trong bảng không quan trọng về mặt kỹ thuật. Nhưng đó không phải là vấn đề, câu hỏi ban đầu chỉ đơn giản là hỏi bạn có thể hoặc không thể làm được. Đừng cho rằng bạn biết yêu cầu của mọi người. Có lẽ họ có một bảng với 100 cột hiện đang được truy vấn bằng cách sử dụng "SELECT * ..." bên trong một số quái dị bị tấn công cùng nhau truy vấn rằng họ sẽ không muốn cố gắng gỡ rối, hãy để một mình thay thế "*" với 100 tên cột. Hoặc có thể họ chỉ là hậu môn về thứ tự của sự vật và muốn có các lĩnh vực liên quan bên cạnh nhau khi duyệt lược đồ với, nói SQL Developer. Có lẽ họ đang đối phó với các nhân viên phi kỹ thuật mà sẽ không biết nhìn vào cuối danh sách 100 cột khi, một cách hợp lý, nó phải ở đâu đó gần đầu.

Không có gì gây khó chịu hơn là đặt câu hỏi trung thực và nhận được câu trả lời cho biết: "bạn không nên làm điều đó". Đó là công việc của tôi, không phải của bạn! Xin đừng nói cho tôi biết cách làm việc của tôi. Chỉ cần giúp đỡ nếu bạn có thể. Cảm ơn!

Ok ... xin lỗi vì rant. Bây giờ ... tại www.orafaq.com nó cho thấy cách giải quyết này.

Giả sử bạn đã chạy:

TẠO tab TABLE1 (col1 NUMBER);

Bây giờ, bạn muốn thêm cột có tên "col2", nhưng bạn muốn đặt cột "col2", "col1" khi thực hiện "SELECT * FROM tbl1;"

Đề xuất là để chạy:

ALTER TABLE tab1 ADD (col2 DATE); tab RENAME1 ĐỂ tab1_old; TẠO TẠO tab1 NHƯ CHỌN 0 AS col1, col1 AS col2 FROM tab1_old;

Tôi thấy điều này vô cùng gây hiểu nhầm. Trước hết, bạn đang điền "col1" với số không, vì vậy, nếu bạn có bất kỳ dữ liệu nào, thì bạn sẽ mất nó bằng cách thực hiện điều này.Thứ hai, nó thực sự đổi tên "col1" thành "col2" và không đề cập đến điều này. Vì vậy, đây là ví dụ của tôi, hy vọng đó là rõ ràng hơn một chút:

Giả sử bạn có một bảng đã được tạo ra với các tuyên bố sau:

CREATE TABLE người dùng (first_name varchar (25), varchar last_name (25));

Bây giờ, giả sử bạn muốn chèn tên miền giữa vào giữa tên_bạn và last_name. Dưới đây là một cách:

ALTER TABLE users ADD middle_name varchar (25); RENAME người dùng CHO users_tmp; TẠO TABLE người dùng NHƯ CHỌN first_name, middle_name, last_name FROM users_tmp; /* và để có biện pháp tốt ... */ DROP TABLE testusers_tmp;

Lưu ý rằng middle_name sẽ mặc định là NULL (ngụ ý bởi câu lệnh ALTER TABLE). Bạn có thể đặt một giá trị mặc định khác trong câu lệnh CREATE TABLE như sau:

TẠO người dùng BẢNG CHỌN first_name, 'một số giá trị mặc định' AS middle_name, last_name FROM users_tmp;

Thủ thuật này có thể hữu ích nếu bạn đang thêm trường ngày với mặc định là sysdate, nhưng bạn muốn tất cả các bản ghi hiện có có giá trị ngày khác (ví dụ: trước đó).

Các vấn đề liên quan