Prefiro corrigir o problema de design como uma correção permanente em vez de perder tempo com a solução alternativa.
Em primeiro lugar, NUNCA armazenar DATA como VARCHAR2 . Toda essa sobrecarga se deve ao fato de que seu design é falho .
'20100231'
Como diabos isso poderia ser uma data válida? Qual calendário tem 31 dias em FEVEREIRO?
Siga esses passos:
- Adicione uma nova coluna com DATE DATA TYPE.
- Atualize a nova coluna com valores de data da coluna antiga usando TO_DATE .
- Faça a aritmética DATE necessária na nova coluna DATE ou trate isso na instrução UPDATE na própria etapa 2.
- Retire a coluna antiga.
- Renomeie a nova coluna para a coluna antiga.
ATUALIZAÇÃO Adicionando uma demonstração
Configuração
SQL> CREATE TABLE t
2 (ymd varchar2(8));
Table created.
SQL>
SQL> INSERT ALL
2 INTO t (ymd)
3 VALUES ('20101112')
4 --INTO t (ymd)
5 -- VALUES ('20100231')
6 INTO t (ymd)
7 VALUES ('20150101')
8 INTO t (ymd)
9 VALUES ('20160101')
10 SELECT * FROM dual;
3 rows created.
SQL>
SQL> COMMIT;
Commit complete.
SQL>
Adicionar nova coluna:
SQL> ALTER TABLE t ADD (dt DATE);
Table altered.
SQL>
FAÇA a atualização necessária
SQL> UPDATE t
2 SET dt =
3 CASE
4 WHEN to_date(ymd, 'YYYYMMDD') > SYSDATE
5 THEN NULL
6 ELSE to_date(ymd, 'YYYYMMDD')
7 END;
3 rows updated.
SQL>
SQL> COMMIT;
Commit complete.
SQL>
Vamos verificar:
SQL> SELECT * FROM t;
YMD DT
-------- ---------
20101112 12-NOV-10
20150101 01-JAN-15
20160101
SQL>
Retire a coluna antiga:
SQL> ALTER TABLE t DROP COLUMN ymd;
Table altered.
SQL>
Renomeie a nova coluna para o nome da coluna antiga
SQL> ALTER TABLE t RENAME COLUMN dt TO ymd;
Table altered.
SQL>
Você acabou de corrigir o problema
SQL> SELECT * FROM t;
YMD
---------
12-NOV-10
01-JAN-15
SQL>