It seems that SUBSTR
can result in a longer column? What's going on here?
CREATE TABLE t (
long_field VARCHAR2(1024)
);
SELECT
column_name,
data_length
FROM
all_tab_cols
WHERE
table_name = 'T';
COLUMN_NAME | DATA_LENGTH |
---|---|
LONG_FIELD | 1024 |
INSERT INTO t ( long_field ) VALUES ( 'abcdef' );
CREATE TABLE t2
AS
SELECT
substr(long_field, instr(long_field, 'c') + 1) short_field
FROM
t;
SELECT
column_name,
data_length
FROM
all_tab_cols
WHERE
table_name = 'T2';
COLUMN_NAME | DATA_LENGTH |
---|---|
SHORT_FIELD | 4096 |
I'm on Oracle 18:
select BANNER
from V$VERSION;
BANNER |
---|
Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production |
SUBSTR
returns a VARCHAR2(4000)
as that is the maximum length sub-string that could be returned from the function.
Just because your function substr(long_field, instr(long_field, 'c') + 1)
returns 'def'
doesn't mean that it changes the data-type to have a data-length that is the bounded by the data (i.e. VARCHAR2(3)
) as SUBSTR
could still (for other data) return a 4000 byte string.
If you want a lower data length then use CAST
:
CREATE TABLE t3 AS
SELECT CAST(
substr(long_field, instr(long_field, 'c') + 1)
AS VARCHAR2(10)
) short_field
FROM t;
Then the data dictionary will contain:
TABLE_NAME | COLUMN_NAME | DATA_LENGTH |
---|---|---|
T3 | SHORT_FIELD | 10 |
T2 | SHORT_FIELD | 4000 |