可以說我有一個表,定義如下萎縮在Oracle列
create table dummy (col1 number(9) not null)
在此dummy.col1的所有值均爲7位數長。現在我想使用alter命令從9 - 7減少此列的長度。甲骨文給我的錯誤,列被修改必須是空的,以降低精度或規模。說得通。
我想問一下,是否有任何解決方法來減小列大小?
- 我無法刪除列中的值。
- 我無法將此列中的值複製到另一列,因爲它有數以萬億計的數據。
可以說我有一個表,定義如下萎縮在Oracle列
create table dummy (col1 number(9) not null)
在此dummy.col1的所有值均爲7位數長。現在我想使用alter命令從9 - 7減少此列的長度。甲骨文給我的錯誤,列被修改必須是空的,以降低精度或規模。說得通。
我想問一下,是否有任何解決方法來減小列大小?
該柱尺寸必須如何數據的物理存儲沒有關係(它們是可變長度)
例如如果存儲在數字中,則數字(2)中的'23'將完全相同(38)
它純粹是對可存儲在列中的最大數量的約束,因此您可以只添加一個約束在列:
ALTER TABLE dummy ADD
CONSTRAINT c1
CHECK (col1 < 9999999)
ENABLE
VALIDATE;
,如果你想讓它去的快一點改變VALIDATE
到NOVALIDATE
顯然這不會檢查現有數據的有效性。
凱文的答案非常好。
唯一的其他方式來做到這一點是
重命名現有列,
創建與舊名稱的新列和新的大小,
問題的更新語句來填充新字段(你說你不能這樣做)
然後刪除重命名的列。
你確定你無法在一個週末找到一些停機時間來執行此任務嗎?
解決方案#1
下面我的解決方案保持原有列的順序。
我發現這很重要,尤其是如果出現罐裝SQL語句
那裏(中間層,客戶端層)指向您的數據庫,並且隱含
SELECTs。
即
SELECT *
FROM tableName
WHERE ...;
INSERT INTO copyTableName(column1,column2,column3,...)
SELECT *
FROM tableName
WHERE ...;
這裏所說:
生成的DDL爲
1.表包含您打算調整
2.所有的關係約束,索引,檢查約束之列,觸發器引用該表。 3 3。引用該表主鍵的其他表的所有外鍵。
確保每個表引用對象DDL是獨立的,獨立於CREATE TABLE DDL的
。
你必須像
/* 1. The table containing the column you intend to resize */
CREATE TABLE tableName
(
column1 TYPE(size) [DEFAULT value] [NOT] NULL,
column2 TYPE(size) [DEFAULT value] [NOT] NULL,
column3 TYPE(size) [DEFAULT value] [NOT] NULL,
...
)
TABLESPACE tsName
[OPTIONS];
/* 2. All the relationship constraints, indexes, check constraints, triggers that reference that table. */
CREATE INDEX indexName ON tableName
(column1)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
CREATE INDEX compositeIndexName ON tableName
(column1,column2,...)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
CREATE UNIQUE INDEX pkName ON tableName
(column2)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
ALTER TABLE tableName ADD (
CHECK (column4 IS NOT NULL));
ALTER TABLE tableName ADD (
CONSTRAINT pkName
PRIMARY KEY
(column2)
USING INDEX
TABLESPACE INDX);
ALTER TABLE tableName ADD (
CONSTRAINT fkName
FOREIGN KEY (column2)
REFERENCES otherTable (column2));
/* 3. All the foreign keys of other tables that reference the primary key of this table. */
ALTER TABLE otherTableName ADD (
CONSTRAINT otherTableFkName
FOREIGN KEY (otherTableColumn2)
REFERENCES tableName (column1));
複製出來只是CREATE TABLE
語句,更改表名和
減少列的你想修改尺寸:
CREATE TABLE tableName_YYYYMMDD
(
column1 TYPE(size) [DEFAULT value] [NOT] NULL,
column2 TYPE(reducedSize) [DEFAULT value] [NOT] NULL,
column3 TYPE(size) [DEFAULT value] [NOT] NULL,
...
)
TABLESPACE tsName
[OPTIONS];
插入從tableName
到tableName_YYYYMMDD
的數據:
INSERT /* APPEND */ INTO tableName_YYYYMMDD(
column1 ,
column2 ,
column3 ,
... )
SELECT
column1 ,
column2 ,
column3 ,
...
FROM tableName;
COMMIT;
刪除所有引用原始表的對象。
另外,刪除引用tableName主鍵pkName的所有外鍵。
別擔心,你已經保存了DDL,所以你可以重新創建它們。
請注意,我在將數據從tableName複製出來後刪除索引。
我這樣做是因爲可能在SELECT上面的
中使用其中一個索引,以便操作更快完成。
DROP INDEX indexName ;
DROP INDEX compositeIndexName ;
DROP UNIQUE INDEX pkName ;
ALTER TABLE tableName DROP CONSTRAINT pkName ;
ALTER TABLE tableName DROP CONSTRAINT fkName ;
ALTER TABLE otherTableName DROP CONSTRAINT otherTableFkName ;
拖放原始表格。
DROP TABLE tableName;
重新命名新表。
ALTER TABLE tableName_YYYYMMDD RENAME TO tableName;
從之前保存的DDL語句中重新創建所有引用對象。
/* 2. All the relationship constraints, indexes, check constraints, triggers that reference that table. */
CREATE INDEX indexName ON tableName
(column1)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
CREATE INDEX compositeIndexName ON tableName
(column1,column2,...)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
CREATE UNIQUE INDEX pkName ON tableName
(column2)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
ALTER TABLE tableName ADD (
CHECK (column4 IS NOT NULL));
ALTER TABLE tableName ADD (
CONSTRAINT pkName
PRIMARY KEY
(column2)
USING INDEX
TABLESPACE INDX);
ALTER TABLE tableName ADD (
CONSTRAINT fkName
FOREIGN KEY (column2)
REFERENCES otherTable (column2));
/* 3. All the foreign keys of other tables that reference the primary key of this table. */
ALTER TABLE otherTableName ADD (
CONSTRAINT otherTableFkName
FOREIGN KEY (otherTableColumn2)
REFERENCES tableName (column1));
解決方案#2
保持列的順序,但不重建可能含有COLUMN2非唯一使用的逐PK索引。
ALTER TABLE tableName ADD (column2Copy TYPE(reducedSize));
UPDATE tableName SET column2Copy = column2;
ALTER TABLE tableName MODIFY (column2 TYPE(size) NULL);
ALTER TABLE tableName DROP CONSTRAINT pkName;
DROP INDEX pkName;
UPDATE tableName SET column2 = null;
ALTER TABLE tableName MODIFY (column2 TYPE(reducedSize));
UPDATE tableName SET column2 = column2Copy;
ALTER TABLE tableName DROP COLUMN column2Copy;
CREATE UNIQUE INDEX pkName ON tableName
(column2)
NOLOGGING
TABLESPACE INDX
NOPARALLEL;
ALTER TABLE tableName ADD (
CONSTRAINT pkName
PRIMARY KEY
(column2)
USING INDEX
TABLESPACE INDX);
COMMIT;
它不會減少此列所消耗的額外存儲空間嗎?即13位數字 –
數字被存儲爲可變長度數據,該大小被用作約束。請參閱:http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1619552483055並在頁面中搜索55 –