จะเกิดอะไรขึ้นเมื่อคุณแก้ไข (ลด) ความยาวของคอลัมน์


10

ช่วยบอกฉันมีสองคอลัมน์ของชนิดNUMBER(โดยไม่ต้องแม่นยำและขนาด) VARCHAR(300)และ ผมเห็นว่าคอลัมน์เหล่านี้เป็นวิธีที่มีขนาดใหญ่เกินไปสำหรับข้อมูลของฉันดังนั้นฉันต้องการที่จะปรับเปลี่ยนให้พวกเขาและNUMBER(11) VARCHAR(10)ดังนั้นถ้าฉันรันคำสั่ง SQL นี้:

ALTER TABLE FOO
    MODIFY(BAR NUMBER(10));
  • ฉันจะสามารถทำเช่นนั้นในคอลัมน์ที่ไม่มีข้อมูลได้หรือไม่
  • ถ้าเป็นเช่นนั้นจะเกิดอะไรขึ้นถ้ามีค่าหนึ่งมากกว่าNUMBER(10)คำทำนายจะบอกฉันเกี่ยวกับมัน?
  • ค่าเริ่มต้นของคอลัมน์จะไม่เปลี่ยนแปลงหากกำหนดไว้ก่อนหน้านี้หรือไม่
  • ตัวเลือก nullable คอลัมน์จะไม่เปลี่ยนแปลงหรือไม่
  • คีย์หลักต่างประเทศรหัสเฉพาะในคอลัมน์นั้นจะไม่มีการเปลี่ยนแปลงหรือไม่
  • ข้อ จำกัด ที่เกี่ยวข้องกับคอลัมน์นั้นจะไม่มีการเปลี่ยนแปลงหรือไม่
  • ดัชนีในคอลัมน์นั้นจะไม่มีการเปลี่ยนแปลงหรือไม่

มีเอกสารอย่างเป็นทางการตอบคำถามของฉันหรือไม่

คำตอบ:


12

ออราเคิลคู่มือผู้ดูแลกล่าวว่าต่อไปนี้:

ใช้คำสั่ง ALTER TABLE ... MODIFY เพื่อแก้ไขนิยามคอลัมน์ที่มีอยู่ คุณสามารถแก้ไขชนิดข้อมูลคอลัมน์ค่าเริ่มต้นข้อ จำกัด ของคอลัมน์นิพจน์คอลัมน์ (สำหรับคอลัมน์เสมือน) และการเข้ารหัสคอลัมน์

คุณสามารถเพิ่มความยาวของคอลัมน์ที่มีอยู่หรือลดลงหากข้อมูลที่มีอยู่ทั้งหมดเป็นไปตามความยาวใหม่ คุณสามารถเปลี่ยนคอลัมน์จากความหมายของไบต์เป็นซีแมนติก CHAR หรือในทางกลับกัน คุณต้องตั้งค่าพารามิเตอร์การเริ่มต้น BLANK_TRIMMING = TRUE เพื่อลดความยาวของคอลัมน์ CHAR แบบไม่ว่างเปล่า

หากคุณกำลังปรับเปลี่ยนตารางเพื่อเพิ่มความยาวของคอลัมน์ประเภทข้อมูล CHAR ให้ตระหนักว่านี่อาจเป็นการดำเนินการที่ต้องใช้เวลานานและอาจต้องใช้พื้นที่เก็บข้อมูลเพิ่มเติมเป็นจำนวนมากโดยเฉพาะอย่างยิ่งหากตารางมีหลายแถว นี่เป็นเพราะค่า CHAR ในแต่ละแถวจะต้องเป็นแผ่นเปล่าเพื่อตอบสนองความยาวคอลัมน์ใหม่

การอ้างอิงภาษา Oracle SQLมีรายละเอียดมากขึ้นรวมถึงต่อไปนี้:

คุณสามารถเปลี่ยนชนิดข้อมูลของคอลัมน์ใด ๆ ได้หากแถวทั้งหมดของคอลัมน์มีโมฆะ อย่างไรก็ตามหากคุณเปลี่ยนชนิดข้อมูลของคอลัมน์ในตารางคอนเทนเนอร์มุมมองที่ปรากฏขึ้นฐานข้อมูล Oracle จะยกเลิกการใช้มุมมองที่ปรากฏที่สอดคล้องกัน

คุณสามารถเพิ่มขนาดของอักขระหรือคอลัมน์ raw หรือความแม่นยำของคอลัมน์ตัวเลขได้เสมอไม่ว่าแถวทั้งหมดจะมีค่า Null หรือไม่ก็ตาม คุณสามารถลดขนาดของชนิดข้อมูลของคอลัมน์ได้ตราบใดที่การเปลี่ยนแปลงไม่ต้องการข้อมูลที่จะแก้ไขฐานข้อมูลจะสแกนข้อมูลที่มีอยู่และส่งคืนข้อผิดพลาดหากข้อมูลที่มีอยู่เกินขีดจำกัดความยาวใหม่

คุณสามารถแก้ไขคอลัมน์ DATE เป็น TIMESTAMP หรือ TIMESTAMP ด้วย LOCAL TIME ZONE คุณสามารถแก้ไข TIMESTAMP ด้วย LOCAL TIME ZONE เป็นคอลัมน์ DATE

หากตารางว่างเปล่าคุณสามารถเพิ่มหรือลดฟิลด์นำหน้าหรือค่าวินาทีเศษของคอลัมน์วันที่หรือช่วงเวลา หากตารางไม่ว่างเปล่าคุณสามารถเพิ่มฟิลด์นำหน้าหรือเสี้ยววินาทีของคอลัมน์วันที่หรือช่วงเวลาเท่านั้น

สำหรับคอลัมน์ CHAR และ VARCHAR2 คุณสามารถเปลี่ยนซีแมนทิกส์ความยาวได้โดยระบุ CHAR (เพื่อระบุความหมายของอักขระสำหรับคอลัมน์ที่ระบุไว้เป็นไบต์) หรือ BYTE (เพื่อระบุความหมายไบต์สำหรับคอลัมน์ที่ แต่เดิมระบุไว้ในตัวอักษร) หากต้องการเรียนรู้ความหมายของความยาวของคอลัมน์ที่มีอยู่ให้สืบค้นคอลัมน์ CHAR_USED ของมุมมองพจนานุกรมข้อมูล ALL_, USER_ หรือ DBA_TAB_COLUMNS

มีข้อมูลเพิ่มเติมและข้อ จำกัด ในเอกสารด้านบน นี่คือการสาธิตการพยายามลดความแม่นยำของคอลัมน์ตัวเลขและลดความยาวของ Varchar2 คุณสามารถลองการเปลี่ยนแปลงอื่น ๆ เพื่อที่คุณจะได้รู้ว่าจะเกิดอะไรขึ้น

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

ข้อความสั่งเปลี่ยนแปลงมีเอาต์พุตต่อไปนี้:

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.

ลดความแม่นยำด้วยการสร้างคอลัมน์ใหม่

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;

ดังนั้นข้อสรุปคือ - ถ้าคุณต้องการลดความแม่นยำหรือปรับขนาดของคอลัมน์และเก็บสิ่งต่าง ๆ เช่นดัชนีกุญแจ ฯลฯ วิธีเดียวที่จะทำก็คือคัดลอกตารางตัดมันเปลี่ยนประเภทคัดลอกข้อมูลกลับไปและวาง ตารางชั่วคราว ไม่มีวิธีใดที่เร็วและสง่างามไปกว่านี้อีกแล้ว?
mnowotka

1
คุณสามารถสร้างคอลัมน์ใหม่คัดลอกข้อมูลสร้างดัชนีใหม่วางคอลัมน์เก่าแล้วเปลี่ยนชื่อใหม่ คุณยังสามารถใช้ DBMS_REDEFINITION หรือคุณสามารถสร้างตารางใหม่คัดลอกข้อมูลวางตารางเก่าและเปลี่ยนชื่อตารางใหม่ หรือคุณสามารถส่งออกตารางวางตารางสร้างใหม่อีกครั้งด้วยคำจำกัดความใหม่และนำเข้าข้อมูล มีหลายวิธีในการทำเช่นนี้ แต่เร็วขึ้น / สวยงามมากขึ้นเป็นสิ่งที่คุณจะต้องตัดสินใจ
Leigh Riffel

อาจเป็นไปได้ว่าคุณสามารถสร้างคอลัมน์ใหม่คัดลอกข้อมูลตั้งค่าคอลัมน์เก่าเป็นโมฆะแก้ไขความยาวคัดลอกข้อมูลจากคอลัมน์ใหม่กลับไปที่คอลัมน์เก่าที่มีการเปลี่ยนแปลงและวางคอลัมน์ใหม่ และทั้งหมดนั้นเพราะ oracle ไม่อนุญาตให้ลดคอลัมน์ตัวเลขแม้ว่าข้อมูลจะพอดี 8- {
Hans-Peter Störr
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.