Oracle 19c 零时默认日期格式,不使用任何格式化函数
Oracle 19c zero hour default date format with time without using any formating function
我正在尝试插入 零小时 20 分钟日期和时间 而不使用任何格式化函数,但我收到一些错误关注
insert into employee(created_date) values('4/Jan/21 00:20:00 AM');
ORA-01849: 小时必须在 1 到 12 之间
如何在 oracle 19c 中插入 零时 而不使用任何格式化函数
without using any formatting function
那将是一个非常糟糕的主意。这意味着您要将 string 插入到 DATE
数据类型列中,希望 Oracle 将“识别”该字符串,将其隐式转换为有效的 DATE
数据类型值并将其插入到列中。有太多的“假设”可能会出错,而且迟早会出错。
样本table:
SQL> create table test (id number, datum date);
Table created.
这是您的查询:
SQL> insert into test (id, datum) values (1, '4/Jan/21 00:20:00 AM');
insert into test (id, datum) values (1, '4/Jan/21 00:20:00 AM')
*
ERROR at line 1:
ORA-01858: a non-numeric character was found where a numeric was expected
我将 to_date
应用于它,使用适当的格式模型(是的,我知道,你不想要那个 - 看看会发生什么):
SQL> insert into test (id, datum) values (1, to_date('4/Jan/21 00:20:00 AM', 'dd/Mon/yy hh:mi:ss am'));
insert into test (id, datum) values (1, to_date('4/Jan/21 00:20:00 AM', 'dd/Mon/yy hh:mi:ss am'))
*
ERROR at line 1:
ORA-01843: not a valid month
为什么“一月”不是有效的月份?好吧,事实并非如此。在克罗地亚(这是我的数据库使用的语言),它是“Sij”。但是好吧,我可以向 TO_DATE
:
添加额外的参数
SQL> insert into test (id, datum) values (1, to_date('4/Jan/21 00:20:00 AM', 'dd/Mon/yy hh:mi:ss am', 'nls_date_language = english'));
insert into test (id, datum) values (1, to_date('4/Jan/21 00:20:00 AM', 'dd/Mon/yy hh:mi:ss am', 'nls_date_language = english'))
*
ERROR at line 1:
ORA-01849: hour must be between 1 and 12
正如 Zakaria 评论的那样,00
是一个无效值;将其更改为 12
:
SQL> insert into test (id, datum) values (1, to_date('4/Jan/21 12:20:00 AM', 'dd/Mon/yy hh:mi:ss am', 'nls_date_language = english'));
1 row created.
没成功。我插入了什么?对,那是午夜过后 20 分钟。
SQL> select id, to_date(datum, 'dd.mm.yyyy hh24:mi:ss') datum from test;
ID DATUM
---------- -------------------
1 04.01.2021 00:20:00
SQL>
如果您坚持要求,请确保 Oracle 理解它。
SQL> rollback;
Rollback complete.
SQL> alter session set nls_date_language = 'english';
Session altered.
SQL> alter session set nls_date_format = 'dd/mon/yy hh:mi:ss am';
Session altered.
SQL> insert into test (id, datum) values (1, '4/Jan/21 12:20:00 AM');
1 row created.
SQL> select * From test;
ID DATUM
---------- ---------------------
1 04/jan/21 12:20:00 AM
SQL>
如果我是你,我不会这样做
一个DATE
是一个二进制数据类型,由7个字节组成(世纪,year-of-century,月,日,时,分,秒);它总是包含这些组件并且从不以任何特定格式存储。
如果你想存储数据和时间,那么你可以使用:
一个DATE
文字和一个INTERVAL DAY TO SECOND
文字:
INSERT INTO employee(created_date)
VALUES ( DATE '2021-01-04' + INTERVAL '00:20:00' HOUR TO SECOND);
这需要 ISO 8601 格式的日期和 24 小时制的时间。
A TIMESTAMP
文字(将隐式转换为 DATE
):
INSERT INTO employee(created_date) VALUES ( TIMESTAMP '2021-01-04 00:20:00');
这需要 ISO 8601 格式的日期和时间(在日期和时间部分之间使用 space 而不是 T
)和 24 小时制时间。
从string-to-date显式转换:
INSERT INTO employee(created_date) VALUES (
TO_DATE(
'4/Jan/21 12:20:00 AM',
'DD/Mon/RR HH12:MI:SS AM',
'NLS_DATE_LANGUAGE=English'
)
);
您可以明确设置您希望使用的格式和语言。 (注意:在 12 小时制中,小时数需要 12
而不是 00
。)
隐式转换自 string-to-date:
首先,设置要与隐式 string-to-date(或 date-to-string)转换一起使用的格式模型:
ALTER SESSION SET NLS_DATE_FORMAT = 'DD/Mon/RR HH12:MI:SS AM';
然后:
INSERT INTO employee(created_date) VALUES ('4/Jan/21 12:20:00 AM');
东西 non-standard,比如直接创建二进制 DATE
值:
CREATE FUNCTION createDate(
year int,
month int,
day int,
hour int,
minute int,
second int
) RETURN DATE DETERMINISTIC
IS
hex CHAR(14);
d DATE;
BEGIN
hex := TO_CHAR( FLOOR( year / 100 ) + 100, 'fm0X' )
|| TO_CHAR( MOD( year, 100 ) + 100, 'fm0X' )
|| TO_CHAR( month, 'fm0X' )
|| TO_CHAR( day, 'fm0X' )
|| TO_CHAR( hour + 1, 'fm0X' )
|| TO_CHAR( minute + 1, 'fm0X' )
|| TO_CHAR( second + 1, 'fm0X' );
DBMS_OUTPUT.PUT_LINE( hex );
DBMS_STATS.CONVERT_RAW_VALUE( HEXTORAW( hex ), d );
RETURN d;
END;
/
然后:
INSERT INTO employee(created_date)
VALUES (createDate(2021,1,4,0,20,0));
选项 1、2 和 3 是创建日期的标准方法。
选项 4 是不好的做法(因为任何用户都可以随时更改自己的会话参数,因此如果 NLS_DATE_FORMAT
与您预期的格式不同,查询将失败)但如果您能保证NLS_DATE_FORMAT
不会改变。
选项 5 仅在为测试目的创建格式错误或错误的日期时真正有用,因为它绕过了正常的错误检查过程。
how to insert zero hour in oracle 19c without using any formatting function
选项 3 是这些选项中唯一使用格式化功能的选项。但是,选项 1、2 和 5 涉及的日期格式设置与您的格式不同,而选项 4 要求您在单独的文件中设置隐式格式模型声明。
我正在尝试插入 零小时 20 分钟日期和时间 而不使用任何格式化函数,但我收到一些错误关注
insert into employee(created_date) values('4/Jan/21 00:20:00 AM');
ORA-01849: 小时必须在 1 到 12 之间
如何在 oracle 19c 中插入 零时 而不使用任何格式化函数
without using any formatting function
那将是一个非常糟糕的主意。这意味着您要将 string 插入到 DATE
数据类型列中,希望 Oracle 将“识别”该字符串,将其隐式转换为有效的 DATE
数据类型值并将其插入到列中。有太多的“假设”可能会出错,而且迟早会出错。
样本table:
SQL> create table test (id number, datum date);
Table created.
这是您的查询:
SQL> insert into test (id, datum) values (1, '4/Jan/21 00:20:00 AM');
insert into test (id, datum) values (1, '4/Jan/21 00:20:00 AM')
*
ERROR at line 1:
ORA-01858: a non-numeric character was found where a numeric was expected
我将 to_date
应用于它,使用适当的格式模型(是的,我知道,你不想要那个 - 看看会发生什么):
SQL> insert into test (id, datum) values (1, to_date('4/Jan/21 00:20:00 AM', 'dd/Mon/yy hh:mi:ss am'));
insert into test (id, datum) values (1, to_date('4/Jan/21 00:20:00 AM', 'dd/Mon/yy hh:mi:ss am'))
*
ERROR at line 1:
ORA-01843: not a valid month
为什么“一月”不是有效的月份?好吧,事实并非如此。在克罗地亚(这是我的数据库使用的语言),它是“Sij”。但是好吧,我可以向 TO_DATE
:
SQL> insert into test (id, datum) values (1, to_date('4/Jan/21 00:20:00 AM', 'dd/Mon/yy hh:mi:ss am', 'nls_date_language = english'));
insert into test (id, datum) values (1, to_date('4/Jan/21 00:20:00 AM', 'dd/Mon/yy hh:mi:ss am', 'nls_date_language = english'))
*
ERROR at line 1:
ORA-01849: hour must be between 1 and 12
正如 Zakaria 评论的那样,00
是一个无效值;将其更改为 12
:
SQL> insert into test (id, datum) values (1, to_date('4/Jan/21 12:20:00 AM', 'dd/Mon/yy hh:mi:ss am', 'nls_date_language = english'));
1 row created.
没成功。我插入了什么?对,那是午夜过后 20 分钟。
SQL> select id, to_date(datum, 'dd.mm.yyyy hh24:mi:ss') datum from test;
ID DATUM
---------- -------------------
1 04.01.2021 00:20:00
SQL>
如果您坚持要求,请确保 Oracle 理解它。
SQL> rollback;
Rollback complete.
SQL> alter session set nls_date_language = 'english';
Session altered.
SQL> alter session set nls_date_format = 'dd/mon/yy hh:mi:ss am';
Session altered.
SQL> insert into test (id, datum) values (1, '4/Jan/21 12:20:00 AM');
1 row created.
SQL> select * From test;
ID DATUM
---------- ---------------------
1 04/jan/21 12:20:00 AM
SQL>
如果我是你,我不会这样做
一个DATE
是一个二进制数据类型,由7个字节组成(世纪,year-of-century,月,日,时,分,秒);它总是包含这些组件并且从不以任何特定格式存储。
如果你想存储数据和时间,那么你可以使用:
一个
DATE
文字和一个INTERVAL DAY TO SECOND
文字:INSERT INTO employee(created_date) VALUES ( DATE '2021-01-04' + INTERVAL '00:20:00' HOUR TO SECOND);
这需要 ISO 8601 格式的日期和 24 小时制的时间。
A
TIMESTAMP
文字(将隐式转换为DATE
):INSERT INTO employee(created_date) VALUES ( TIMESTAMP '2021-01-04 00:20:00');
这需要 ISO 8601 格式的日期和时间(在日期和时间部分之间使用 space 而不是
T
)和 24 小时制时间。从string-to-date显式转换:
INSERT INTO employee(created_date) VALUES ( TO_DATE( '4/Jan/21 12:20:00 AM', 'DD/Mon/RR HH12:MI:SS AM', 'NLS_DATE_LANGUAGE=English' ) );
您可以明确设置您希望使用的格式和语言。 (注意:在 12 小时制中,小时数需要
12
而不是00
。)隐式转换自 string-to-date:
首先,设置要与隐式 string-to-date(或 date-to-string)转换一起使用的格式模型:
ALTER SESSION SET NLS_DATE_FORMAT = 'DD/Mon/RR HH12:MI:SS AM';
然后:
INSERT INTO employee(created_date) VALUES ('4/Jan/21 12:20:00 AM');
东西 non-standard,比如直接创建二进制
DATE
值:CREATE FUNCTION createDate( year int, month int, day int, hour int, minute int, second int ) RETURN DATE DETERMINISTIC IS hex CHAR(14); d DATE; BEGIN hex := TO_CHAR( FLOOR( year / 100 ) + 100, 'fm0X' ) || TO_CHAR( MOD( year, 100 ) + 100, 'fm0X' ) || TO_CHAR( month, 'fm0X' ) || TO_CHAR( day, 'fm0X' ) || TO_CHAR( hour + 1, 'fm0X' ) || TO_CHAR( minute + 1, 'fm0X' ) || TO_CHAR( second + 1, 'fm0X' ); DBMS_OUTPUT.PUT_LINE( hex ); DBMS_STATS.CONVERT_RAW_VALUE( HEXTORAW( hex ), d ); RETURN d; END; /
然后:
INSERT INTO employee(created_date) VALUES (createDate(2021,1,4,0,20,0));
选项 1、2 和 3 是创建日期的标准方法。
选项 4 是不好的做法(因为任何用户都可以随时更改自己的会话参数,因此如果 NLS_DATE_FORMAT
与您预期的格式不同,查询将失败)但如果您能保证NLS_DATE_FORMAT
不会改变。
选项 5 仅在为测试目的创建格式错误或错误的日期时真正有用,因为它绕过了正常的错误检查过程。
how to insert zero hour in oracle 19c without using any formatting function
选项 3 是这些选项中唯一使用格式化功能的选项。但是,选项 1、2 和 5 涉及的日期格式设置与您的格式不同,而选项 4 要求您在单独的文件中设置隐式格式模型声明。