[20241118]invalid date 0000-00-00(zero year)的输入.txt

[20241118]invalid date 0000-00-00(zero year)的输入.txt

--//昨天看了链接:https://www.anbob.com/archives/8511.html,类似的问题以前我也遇到过,我记忆里第一次在toad下,如果在浏
--//览数据模式,点击显示0000-00-00的grid会报错,提示invalid date。

--//我一直不明白这些日期输入如何输入的,在sqlplus下无法输入。最后只能认为一个程序OCI接受这些输入。
--//不过作者提供在sqlplu输入的方式,测试看看。

1.环境:
SCOTT@book01p> @ver2
==============================
PORT_STRING                   : x86_64/Linux 2.4.xx
VERSION                       : 21.0.0.0.0
BANNER                        : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL                   : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY                 : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID                        : 0
PL/SQL procedure successfully completed.

2.测试:
SCOTT@book01p> create table test2(ct date);
Table created.

SCOTT@book01p> insert into test2 values (0);
insert into test2 values (0)
                          *
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected DATE got NUMBER

SCOTT@book01p> insert into test2 values(to_date('00000000','yyyymmdd'));
insert into test2 values(to_date('00000000','yyyymmdd'))
                                 *
ERROR at line 1:
ORA-01843: not a valid month

SCOTT@book01p> select to_date('0000-00-00','yyyy-mm-dd');
select to_date('0000-00-00','yyyy-mm-dd')
                                        *
ERROR at line 1:
ORA-00923: FROM keyword not found where expected

--//与我以前测试类似,sqlplus下无法插入0000-00-00日期。

--//按照日期的转换格式计算RAW换算方法,'0000-00-00 00:00:00'拼接RAW 后是100,100,0,0,1,1,1, 转换为16进制是64640000010101。

WITH
    FUNCTION display_raw(rawval RAW, type VARCHAR2)
    RETURN VARCHAR2
    IS
        cn  NUMBER;
        cv  VARCHAR2(128);
        cd  DATE;
        cnv NVARCHAR2(128);
        cr  ROWID;
        cc  CHAR(128);
    BEGIN
        IF (type = 'NUMBER') THEN
            dbms_stats.convert_raw_value(rawval, cn);
            RETURN to_char(cn);
        ELSIF (type = 'VARCHAR2') THEN
            dbms_stats.convert_raw_value(rawval, cv);
            RETURN to_char(cv);
        ELSIF (type = 'DATE') THEN
            dbms_stats.convert_raw_value(rawval, cd);
            RETURN to_char(cd);
        ELSIF (type = 'NVARCHAR2') THEN
            dbms_stats.convert_raw_value(rawval, cnv);
            RETURN to_char(cnv);
        ELSIF (type = 'ROWID') THEN
            dbms_stats.convert_raw_value(rawval, cr);
            RETURN to_char(cr);
        ELSIF (type = 'VARCHAR2') THEN
            dbms_stats.convert_raw_value(rawval, cc);
            RETURN to_char(cc);
        ELSE
            RETURN 'UNKNOWN DATATYPE';
        END IF;
    END;
select display_raw('64640000010101','DATE') x from dual;
/

X
------------------------------
0000-00-00 00:00:00

WITH
    FUNCTION display_raw(rawval RAW, type VARCHAR2)
    RETURN VARCHAR2
    IS
        cn  NUMBER;
        cv  VARCHAR2(128);
        cd  DATE;
        cnv NVARCHAR2(128);
        cr  ROWID;
        cc  CHAR(128);
    BEGIN
        IF (type = 'NUMBER') THEN
            dbms_stats.convert_raw_value(rawval, cn);
            RETURN to_char(cn);
        ELSIF (type = 'VARCHAR2') THEN
            dbms_stats.convert_raw_value(rawval, cv);
            RETURN to_char(cv);
        ELSIF (type = 'DATE') THEN
            dbms_stats.convert_raw_value(rawval, cd);
            RETURN to_char(cd);
        ELSIF (type = 'NVARCHAR2') THEN
            dbms_stats.convert_raw_value(rawval, cnv);
            RETURN to_char(cnv);
        ELSIF (type = 'ROWID') THEN
            dbms_stats.convert_raw_value(rawval, cr);
            RETURN to_char(cr);
        ELSIF (type = 'VARCHAR2') THEN
            dbms_stats.convert_raw_value(rawval, cc);
            RETURN to_char(cc);
        ELSE
            RETURN 'UNKNOWN DATATYPE';
        END IF;
    END;
insert into test2 select display_raw('64640000010101','DATE') x from dual;
/

insert into test2 select display_raw('64640000010101','DATE') x from dual
*
ERROR at line 34:
ORA-00928: missing SELECT keyword
--//oracle不支持这样写法,不知道写错在哪里。

create or replace function stats_raw_to_date (p_in raw) return date is
  v_date date;
  v_char varchar2(25);
begin
  dbms_stats.CONVERT_RAW_VALUE(p_in, v_date);
  return v_date;
exception
  when others then return null;
end;
/


SCOTT@book01p> insert into test2  select stats_raw_to_date('64640000010101') x from dual;
1 row created.

SCOTT@book01p> commit ;
Commit complete.

SCOTT@book01p> select * from test2;
CT
-------------------
2024-11-18 09:58:22
0000-00-00 00:00:00

--//21c也提供dbms_stats.CONVERT_RAW_TO_DATE函数。
SCOTT@book01p> @ desc_proc sys dbms_stats CONVERT_RAW_to_%
INPUT OWNER PACKAGE_NAME OBJECT_NAME
sample : @desc_proc sys dbms_stats gather_%_stats
OWNER      PACKAGE_NAME OBJECT_NAME                      SEQUENCE ARGUMENT_NAME DATA_TYPE     IN_OUT    DEFAULTED
---------- ------------ ------------------------------ ---------- ------------- ------------- --------- ----------
SYS        DBMS_STATS   CONVERT_RAW_TO_VARCHAR2                 1               VARCHAR2      OUT       N
                                                                2 RAWVAL        RAW           IN        N

                        CONVERT_RAW_TO_DATE                     1               DATE          OUT       N
                                                                2 RAWVAL        RAW           IN        N

                        CONVERT_RAW_TO_NUMBER                   1               NUMBER        OUT       N
                                                                2 RAWVAL        RAW           IN        N

                        CONVERT_RAW_TO_BIN_FLOAT                1               BINARY_FLOAT  OUT       N
                                                                2 RAWVAL        RAW           IN        N

                        CONVERT_RAW_TO_BIN_DOUBLE               1               BINARY_DOUBLE OUT       N
                                                                2 RAWVAL        RAW           IN        N

                        CONVERT_RAW_TO_NVARCHAR                 1               NVARCHAR2     OUT       N
                                                                2 RAWVAL        RAW           IN        N

                        CONVERT_RAW_TO_ROWID                    1               ROWID         OUT       N
                                                                2 RAWVAL        RAW           IN        N
14 rows selected.
--//有了这些函数方便多了,以前11g版本仅仅有dbms_stats.convert_raw_value,而且返回值保存在第2个参数里面。
--//于是才有了上面的函数display_raw。

SCOTT@book01p> select dbms_stats.CONVERT_RAW_TO_DATE('64640000010101') from dual ;
DBMS_STATS.CONVERT_
-------------------
0000-00-00 00:00:00

SCOTT@book01p> insert into test2 select dbms_stats.CONVERT_RAW_TO_DATE('64640000010101') from dual ;
1 row created.

SCOTT@book01p> commit ;
Commit complete.

SCOTT@book01p> select * from test2 where ct=dbms_stats.CONVERT_RAW_TO_DATE('64640000010101');
CT
-------------------
0000-00-00 00:00:00
0000-00-00 00:00:00
--//顺便提一下目前的toad 12.7版本,显示的是 0001/1/1.

select dump(ct,16) c10 ,test2.* from test2
C10                              CT                   
-------------------------------- ---------------------
Typ=12 Len=7: 78,7c,b,12,a,3b,17 2024-11-18 09:58:22  
Typ=12 Len=7: 64,64,0,0,1,1,1    0001-01-01 00:00:00  
Typ=12 Len=7: 64,64,0,0,1,1,1    0001-01-01 00:00:00  
已选择 3 行。

posted @ 2024-11-18 21:45  lfree  阅读(1)  评论(0编辑  收藏  举报