I would like to partition a table using a function over a column, due to I don't want to create a new column. My table Example has a column DATE_VARCHAR (format 'YYYY-MM-DD') and I would like to partition it given the month of the date, but I have some problems.
- I can't ALTER my table to add the partitioning (Oracle requirements), so I create a backup table, to backup the data.
I can't add a column in the new structure (client requirements), so if I want to do the partitioning using substring function over DATE_VARCHAR, I get a syntax error:
CREATE TABLE PRUEBA( DATE_VARCHAR VARCHAR2(10), SOME_COLUMNS VARCHAR(50) ) PARTITION BY LIST (SUBSTR(DATE_VARCHAR,6,2)) (PARTITION p1 VALUES ('01','05','09'), PARTITION p2 VALUES ('02','06','10'), PARTITION p3 VALUES ('03','07','11'), PARTITION p4 VALUES ('04','08','12'));
Due to it expects an identifier column (column name), in spite of I get the following error: ORA-00907 missing right parenthesis.
If I create a column with the month value:
CREATE TABLE Example( DATE_VARCHAR VARCHAR2(10), SOME_COLUMNS VARCHAR(50), MONTH VARCHAR2(2) GENERATED ALWAYS AS (SUBSTR(DATE_VARCHAR,6,2)) VIRTUAL ) PARTITION BY LIST (MONTH) (PARTITION p1 VALUES ('01','05','09'), PARTITION p2 VALUES ('02','06','10'), PARTITION p3 VALUES ('03','07','11'), PARTITION p4 VALUES ('04','08','12'));
I get the following error: ORA-12899 value too large for column %s (actual: %s, maximum: %s), due to the new column is only length 2 (and the source column is length 10); in spite of I'm doing a substring of length 2.
The only way to do this, is the 3? Exists another way to solve this?
Edit: If I do the next, it works for me:
CREATE TABLE Example(
DATE_VARCHAR VARCHAR2(10),
SOME_COLUMNS VARCHAR(50),
MONTH VARCHAR2(**10**) GENERATED ALWAYS AS
(SUBSTR(DATE_VARCHAR,6,2)) VIRTUAL
)
PARTITION BY LIST (MONTH)
(PARTITION p1 VALUES ('01','05','09'),
PARTITION p2 VALUES ('02','06','10'),
PARTITION p3 VALUES ('03','07','11'),
PARTITION p4 VALUES ('04','08','12'));
But I don't understand why column needs have length equal 10, and not 2, having in count the substring.
Edit: Execution trough sqlplus:
SQL> CREATE TABLE tabx(
2 DATE_VARCHAR VARCHAR2(10),
SOME_COLUMNS VARCHAR(50),
MONTH VARCHAR2(2) GENERATED ALWAYS AS (SUBSTR(DATE_VARCHAR,6,2)) VIRTUAL
)
PARTITION BY LIST (MONTH)
(PARTITION p1 VALUES ('01','05','09'),
PARTITION p2 VALUES ('02','06','10'),
PARTITION p3 VALUES ('03','07','11'),
PARTITION p4 VALUES ('04','08','12'),
-- need default in case of bad data format
partition others values (default)
);
-- NOTE: this WON'T work now after adding VIRTUAL column
--insert into tabx values ('2015-12-01', 'ABC');
-- but this will (must specify columns)
3 4 5 6 7 8 9 10 11 12 13 insert into tabx(date_varchar,some_columns) values ('2016-01-01', 'XYZ');
MONTH VARCHAR2(2) GENERATED ALWAYS AS (SUBSTR(DATE_VARCHAR,6,2)) VIRTUAL
*
ERROR at line 4:
ORA-12899: value too large for column "MONTH" (actual: 2, maximum: 8)
SQL> SQL> SQL> SQL> SQL> SQL> insert into tabx(date_varchar,some_columns) values ('2016-01-01', 'XYZ')
*
ERROR at line 1:
ORA-00942: table or view does not exist