Điều gì xảy ra khi bạn sửa đổi (giảm) độ dài của cột?


10

Hãy nói rằng tôi có hai cột loại NUMBER(không có độ chính xác và tỷ lệ) và VARCHAR(300). Tôi thấy rằng các cột này quá lớn so với dữ liệu của tôi, vì vậy tôi muốn sửa đổi chúng thành NUMBER(11)VARCHAR(10). Vì vậy, nếu tôi chạy câu lệnh SQL này:

ALTER TABLE FOO
    MODIFY(BAR NUMBER(10));
  • Tôi sẽ có thể làm điều đó trên cột không trống?
  • Nếu vậy, nếu có một giá trị nào lớn hơn NUMBER(10), thì nhà tiên tri sẽ cho tôi biết về nó?
  • Giá trị mặc định của cột sẽ không thay đổi nếu được xác định trước?
  • Tùy chọn cột nullable sẽ không thay đổi?
  • Khóa chính, nước ngoài, khóa duy nhất trên cột đó sẽ không thay đổi?
  • Những hạn chế liên quan đến cột đó sẽ không thay đổi?
  • Các chỉ mục trên các cột đó sẽ không thay đổi?

Có tài liệu chính thức nào trả lời câu hỏi của tôi không?

Câu trả lời:


12

Các Oracle Quản trị Hướng dẫn cho biết những điều sau đây:

Sử dụng câu lệnh ALTER TABLE ... MODIFY để sửa đổi định nghĩa cột hiện có. Bạn có thể sửa đổi loại dữ liệu cột, giá trị mặc định, ràng buộc cột, biểu thức cột (đối với cột ảo) và mã hóa cột.

Bạn có thể tăng chiều dài của một cột hiện có hoặc giảm nó, nếu tất cả dữ liệu hiện có thỏa mãn độ dài mới. Bạn có thể thay đổi một cột từ ngữ nghĩa byte sang ngữ nghĩa CHAR hoặc ngược lại. Bạn phải đặt tham số khởi tạo BLANK_TRIMMING = TRUE để giảm độ dài của cột CHAR không trống.

Nếu bạn đang sửa đổi bảng để tăng độ dài của cột kiểu dữ liệu CHAR, hãy nhận ra rằng đây có thể là một hoạt động tốn thời gian và có thể yêu cầu lưu trữ bổ sung đáng kể, đặc biệt nếu bảng có nhiều hàng. Điều này là do giá trị CHAR trong mỗi hàng phải được đệm trống để đáp ứng độ dài cột mới.

Các Oracle SQL Language Reference có chi tiết hơn bao gồm những điều sau đây:

Bạn có thể thay đổi kiểu dữ liệu của bất kỳ cột nào nếu tất cả các hàng của cột chứa null. Tuy nhiên, nếu bạn thay đổi kiểu dữ liệu của một cột trong bảng chứa khung nhìn được cụ thể hóa, thì Cơ sở dữ liệu Oracle sẽ vô hiệu hóa khung nhìn cụ thể hóa tương ứng.

Bạn luôn có thể tăng kích thước của một ký tự hoặc cột thô hoặc độ chính xác của cột số, cho dù tất cả các hàng có chứa null hay không. Bạn có thể giảm kích thước của loại dữ liệu của cột miễn là thay đổi không yêu cầu dữ liệu phải sửa đổi. Cơ sở dữ liệu quét dữ liệu hiện có và trả về lỗi nếu dữ liệu tồn tại vượt quá giới hạn độ dài mới.

Bạn có thể sửa đổi cột NGÀY thành TIMESTAMP hoặc TIMESTAMP VỚI KHU VỰC THỜI GIAN. Bạn có thể sửa đổi bất kỳ THỜI GIAN NÀO VỚI KHU VỰC THỜI GIAN LỘC thành cột NGÀY.

Nếu bảng trống, thì bạn có thể tăng hoặc giảm trường hàng đầu hoặc giá trị thứ hai phân đoạn của cột thời gian hoặc cột thời gian. Nếu bảng không trống, thì bạn chỉ có thể tăng trường hàng đầu hoặc giây thứ hai của cột thời gian hoặc cột thời gian.

Đối với các cột CHAR và VARCHAR2, bạn có thể thay đổi ngữ nghĩa độ dài bằng cách chỉ định CHAR (để chỉ ra ngữ nghĩa ký tự cho một cột được chỉ định ban đầu theo byte) hoặc BYTE (để chỉ ra ngữ nghĩa byte cho một cột được chỉ định ban đầu bằng các ký tự). Để tìm hiểu ngữ nghĩa độ dài của các cột hiện có, hãy truy vấn cột CHAR_USED của chế độ xem từ điển dữ liệu ALL_, USER_ hoặc DBA_TAB_COLUMNS.

Có thêm thông tin và hạn chế trong tài liệu trên. Dưới đây là một minh chứng về việc cố gắng giảm độ chính xác của cột Số và giảm độ dài của Varchar2. Bạn có thể thử những thay đổi khác để bạn sẽ biết điều gì sẽ xảy ra.

--Setup.
DROP TABLE FOO;
CREATE TABLE FOO (BAR Number, BAR2 VARCHAR2(300));
INSERT INTO FOO (SELECT Level, RPAD(to_char(Level),10*Level,to_char(Level)) 
   FROM DUAL CONNECT BY Level <=20);
COMMIT;
SELECT * FROM FOO;

--Reduce Number to Number(10).
ALTER TABLE FOO MODIFY (BAR NUMBER (10));

--Reduce Varchar2(300) to Varchar2(100) (data would be truncated).
ALTER TABLE FOO MODIFY (BAR2 VARCHAR2(100));

--Reduce Varchar2(300) to Varchar2(200) (no data would be truncated).
ALTER TABLE FOO MODIFY (BAR2 VARCHAR2(200));

Các báo cáo thay đổi có đầu ra sau đây:

ALTER TABLE FOO MODIFY (BAR NUMBER (10))
Error report:
SQL Error: ORA-01440: column to be modified must be empty to decrease precision or scale
01440. 00000 -  "column to be modified must be empty to decrease precision or scale"

ALTER TABLE FOO MODIFY (BAR2 VARCHAR2(100))
Error report:
SQL Error: ORA-01441: cannot decrease column length because some value is too big
01441. 00000 -  "cannot decrease column length because some value is too big"

table FOO altered.

Giảm độ chính xác bằng cách tạo một cột mới.

ALTER TABLE FOO ADD (BAR3 NUMBER(10));
UPDATE FOO SET Bar3 = Bar;
ALTER TABLE FOO DROP COLUMN BAR;
ALTER TABLE FOO RENAME COLUMN BAR3 TO BAR;

Vì vậy, kết luận là - nếu bạn muốn giảm độ chính xác hoặc tỷ lệ của cột và giữ những thứ như chỉ mục, khóa, v.v ... cách duy nhất để làm là sao chép bảng, cắt bớt nó, thay đổi loại, sao chép dữ liệu trở lại và thả cái bàn tạm. Không có cách nào nhanh hơn, thanh lịch hơn?
mnowotka

1
Chà, bạn có thể tạo một cột mới, sao chép dữ liệu, tạo lại chỉ mục, thả cột cũ và đổi tên cột mới. Bạn cũng có thể sử dụng DBMS_REDEFINITION hoặc bạn có thể tạo một bảng mới, sao chép dữ liệu, thả bảng cũ và đổi tên bảng mới. Hoặc bạn có thể xuất bảng, thả bảng, tạo lại với định nghĩa mới và họ nhập dữ liệu. Có rất nhiều cách để làm điều này, nhưng nhanh hơn / thanh lịch hơn là điều bạn sẽ phải quyết định.
Leigh Riffel

Có lẽ bạn cũng có thể tạo một cột mới, sao chép dữ liệu vào cột đó, đặt cột cũ thành null, sửa đổi độ dài của nó, sao chép dữ liệu từ cột mới trở lại cột cũ đã thay đổi và thả cột mới. Và tất cả điều đó bởi vì oracle không cho phép giảm các cột số mặc dù dữ liệu sẽ phù hợp. 8- {
Hans-Peter Störr
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.