Bir sütunun uzunluğunu değiştirdiğinizde (azalttığınızda) ne olur?


10

Diyelim ki iki tür sütunum var NUMBER(kesinlik ve ölçek olmadan) ve VARCHAR(300). Bu sütunların verilerim için çok büyük olduğunu gördüm, bu yüzden onları NUMBER(11)ve olarak değiştirmek istiyorum VARCHAR(10). Bu SQL deyimini çalıştırırsanız:

ALTER TABLE FOO
    MODIFY(BAR NUMBER(10));
  • Bunu boş olmayan sütunda yapabilir miyim?
  • Eğer öyleyse, ne Büyük bir değer varsa NUMBER(10)oracle bana bundan bahseder mi?
  • Daha önce tanımlanmışsa, sütun varsayılan değerleri değişmez mi?
  • Sütun sıfırlanabilir seçeneği değişmeyecek mi?
  • Bu sütundaki birincil, yabancı, benzersiz anahtar değişmeyecek mi?
  • Bu sütunları içeren kısıtlamalar değişmeden mi kalacak?
  • Bu sütunlardaki dizinler değişmeden kalacak mı?

Sorularıma cevap veren resmi bir belge var mı?

Yanıtlar:


12

Oracle Yönetici Kılavuzu aşağıdakileri diyor ki:

Varolan bir sütun tanımını değiştirmek için ALTER TABLE ... MODIFY deyimini kullanın. Sütun veri türünü, varsayılan değeri, sütun kısıtlamasını, sütun ifadesini (sanal sütunlar için) ve sütun şifrelemesini değiştirebilirsiniz.

Mevcut bir sütunun uzunluğunu artırabilir veya mevcut verilerin tümü yeni uzunluğu karşılıyorsa sütunu azaltabilirsiniz. Bir sütunu bayt semantiğinden CHAR semantiğine veya tam tersine değiştirebilirsiniz. Boş olmayan bir CHAR sütununun uzunluğunu azaltmak için başlatma parametresini BLANK_TRIMMING = TRUE olarak ayarlamanız gerekir.

CHAR veri türü sütununun uzunluğunu artırmak için bir tabloyu değiştiriyorsanız, bunun zaman alıcı bir işlem olabileceğini ve özellikle tablo çok satır içeriyorsa önemli miktarda ek depolama gerektirebileceğini unutmayın. Bunun nedeni, yeni sütun uzunluğunu karşılamak için her satırdaki CHAR değerinin boş olarak doldurulması gerektiğidir.

Oracle SQL dili başvuru aşağıda dahil çok fazla detay vardır:

Sütunun tüm satırları null içeriyorsa, herhangi bir sütunun veri türünü değiştirebilirsiniz. Ancak, bir materyalize görünüm kapsayıcısı tablosundaki bir sütunun veri türünü değiştirirseniz, Oracle Database karşılık gelen materyalize görünümü geçersiz kılar.

Tüm satırlar null olsa da olmasa da, bir karakterin veya ham sütunun boyutunu ya da sayısal bir sütunun kesinliğini her zaman artırabilirsiniz. Değişiklik verilerin değiştirilmesini gerektirmediği sürece, bir sütunun veri türünün boyutunu azaltabilirsiniz.Veritabanı mevcut verileri tarar ve yeni uzunluk sınırını aşan veriler varsa bir hata döndürür.

Bir TARİH sütununu YEREL ZAMAN BÖLGESİ İLE TIMESTAMP veya TIMESTAMP olarak değiştirebilirsiniz. Herhangi bir ZAMAN YERİ BÖLGESİ İLE TIMESTAMP'i bir TARİH sütununa değiştirebilirsiniz.

Tablo boşsa, tarih veya aralık sütununun ön alanını veya kesirli ikinci değerini artırabilir veya azaltabilirsiniz. Tablo boş değilse, tarih veya aralık sütununun yalnızca ön alanını veya kesirli saniyesini artırabilirsiniz.

CHAR ve VARCHAR2 sütunları için, CHAR (başlangıçta bayt olarak belirtilen bir sütun için karakter semantiğini belirtmek için) veya BYTE (orijinal olarak karakterlerde belirtilen bir sütun için bayt semantiğini belirtmek için) belirterek uzunluk semantiğini değiştirebilirsiniz. Varolan sütunların uzunluk anlamlarını öğrenmek için, ALL_, USER_ veya DBA_TAB_COLUMNS veri sözlüğü görünümünün CHAR_USED sütununu sorgulayın.

Yukarıdaki belgelerde ek bilgi ve kısıtlamalar bulunmaktadır. Burada, bir Sayı sütununun hassasiyetini azaltmaya ve bir Varchar2'nin uzunluğunu azaltmaya çalıştığınız gösterilmiştir. Ne olacağını bilmek için diğer değişiklikleri deneyebilirsiniz.

--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 ifadeleri şu çıktıya sahiptir:

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.

Yeni bir sütun oluşturarak hassasiyeti azaltın.

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;

Yani, sonuç - sütunun hassasiyetini veya ölçeğini azaltmak ve dizinler, anahtarlar vb. Gibi şeyleri tutmak istiyorsanız, tabloyu kopyalamanın, kesmenin, türleri değiştirmenin, verileri tekrar kopyalayıp bırakmanın geçici tablo. Daha hızlı, daha zarif bir yol yok mu?
mnowotka

1
Yeni bir sütun oluşturabilir, verileri kopyalayabilir, dizini yeniden oluşturabilir, eski sütunu bırakabilir ve yenisini yeniden adlandırabilirsiniz. Ayrıca DBMS_REDEFINITION kullanabilir veya yeni bir tablo oluşturabilir, verileri kopyalayabilir, eski tabloyu bırakıp yenisini yeniden adlandırabilirsiniz. Veya tabloyu dışa aktarabilir, bırakabilir, yeni tanımla yeniden oluşturabilir ve verileri içe aktarabilirsiniz. Bunu yapmanın birçok yolu vardır, ancak daha hızlı / daha zarif karar vermeniz gereken bir şeydir.
Leigh Riffel

Muhtemelen yeni bir sütun oluşturabilir, verileri ona kopyalayabilir, eski sütunu boş olarak ayarlayabilir, uzunluğunu değiştirebilir, verileri yeni sütundan değiştirilen eski sütuna geri kopyalayabilir ve yeni sütunu bırakabilirsiniz. Ve tüm bunlar, çünkü oracle veri sığsa bile sayısal sütunların azaltılmasına izin vermez. 8- {
Hans-Peter Störr
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.