如何在 Oracle 表中插入 DateTime 值
本文解释了如何使用 INSERT 语句将带有或不带时间的 DATE 插入到 Oracle 表中。
引言
将日期和时间存储在 DATE
字段中是一个很好的习惯。但是,你实际上如何将它们插入到你的表中呢?
在尝试将一个我认为应该有效的值插入到一个表中时,我曾多次迷失方向,但我收到了一些格式或数据类型错误。
所以,我将在本文中通过一个例子来告诉你如何做到这一点。
我们的示例表
让我们创建一个示例表。
CREATE TABLE student (
first_name VARCHAR2(50),
last_name VARCHAR2(50),
date_of_birth DATE
);
此表仅用于我们的示例,所以让我们忽略它没有 ID
字段的事实。
我们如何将数据插入到这个表中?
INSERT INTO student (first_name, last_name, date_of_birth) VALUES ('Adam', 'Jones', '12/01/2016');
这是发生的事情
Error starting at line : 1 in command -
INSERT INTO student (first_name, last_name, date_of_birth) VALUES ('Adam', 'Jones', '12/01/2016')
Error report -
SQL Error: ORA-01843: not a valid month
01843. 00000 - "not a valid month"
*Cause:
*Action:
现在,发生这种情况是因为我提供的日期值 (12/01/2016
) 根据该表无效。
我怎样才能让它加载?
使用 TO_DATE
函数。
使用 TO_DATE 函数插入日期时间值
TO_DATE
函数将 string
值转换为 DATE
值。它非常适合将日期插入到表中。
让我们再次尝试,这次使用 TO_DATE
函数。
INSERT INTO student (first_name, last_name, date_of_birth)
VALUES ('Adam', 'Jones', TO_DATE('12/01/2016', 'DD/MM/YYYY'));
1 row inserted.
这一次,它成功了。
让我们检查一下该表。
SELECT first_name, last_name, date_of_birth
FROM student;
名字 | 姓氏 | 出生日期 |
亚当 | 琼斯 | 12/一月/16 |
如果我更改格式以使用 MM/DD/YYYY
,则此 INSERT
语句也可以工作。
INSERT INTO student (first_name, last_name, date_of_birth)
VALUES ('Brad', 'Smith', TO_DATE('12/01/2016', 'MM/DD/YYYY'));
1 row inserted.
让我们再次检查一下该表。
SELECT first_name, last_name, date_of_birth
FROM student;
名字 | 姓氏 | 出生日期 |
亚当 | 琼斯 | 12/一月/16 |
布拉德 | 史密斯 | 01/十二月/16 |
插入日期和时间
这些例子很有用,但它们只显示了日期。时间呢?
让我们尝试另一个例子,但包括一个时间。
INSERT INTO student (first_name, last_name, date_of_birth)
VALUES ('Carrie', 'Johnson', TO_DATE('12/01/2016 14:08:25', 'MM/DD/YYYY HH24:MI:SS'));
1 row inserted.
让我们再次看一下该表。
SELECT first_name, last_name, date_of_birth
FROM student;
名字 | 姓氏 | 出生日期 |
亚当 | 琼斯 | 12/一月/16 |
布拉德 | 史密斯 | 01/十二月/16 |
凯莉 | 约翰逊 | 01/十二月/16 |
等等,时间怎么了?我确定我在 INSERT
语句中包含了时间?
我的确包含了。但是,这里没有显示的原因是 DATE 的默认输出格式可能不包括时间。
我们可以在 NLS_SESSION_PARAMETERS
表中进行检查。
SELECT *
FROM nls_session_parameters
WHERE parameter = 'NLS_DATE_FORMAT';
参数 | VALUE |
NLS_DATE_FORMAT | DD/MON/RR |
这意味着每当我们输出 DATE
值时,它将以此格式显示。RR
是一个两位数的年份值。MON
是缩写的月份值。
这与我们的 01/DEC/16
和 12/JAN/16
值匹配。
那么,我们如何显示时间呢?
我们可以通过两种方式来做到这一点。
更改会话日期格式
我们可以更改会话的日期格式,这意味着它只是暂时更改,并在我们结束会话时恢复。
ALTER SESSION SET nls_date_format = 'DD/MON/YYYY hh24:mi:ss';
Session altered.
现在,让我们再次运行我们的查询。
SELECT first_name, last_name, date_of_birth
FROM student;
名字 | 姓氏 | 出生日期 |
亚当 | 琼斯 | 12/一月/16 |
布拉德 | 史密斯 | 01/十二月/16 |
凯莉 | 约翰逊 | 01/十二月/16 14:08:25 |
我们得到相同的行,但时间现在显示出来了。
还有另一种方法可以在不调整会话的情况下显示时间组件。
使用 TO_CHAR 函数格式化输出
你还可以使用 TO_CHAR
函数来格式化输出,它将 date
转换为 varchar
值。
让我们将会话恢复到原来的状态。
ALTER SESSION SET nls_date_format = 'DD/MON/RR';
Session altered.
现在,让我们从我们的表中选择。
SELECT first_name, last_name, date_of_birth
FROM student;
名字 | 姓氏 | 出生日期 |
亚当 | 琼斯 | 12/一月/16 |
布拉德 | 史密斯 | 01/十二月/16 |
凯莉 | 约翰逊 | 01/十二月/16 |
我们可以看到输出现在只显示日期,而不显示时间。
让我们使用 TO_CHAR
函数。
SELECT first_name, last_name, TO_CHAR(date_of_birth, 'DD/MON/YYYY HH24:MI:SS') AS date_output
FROM student;
名字 | 姓氏 | 出生日期 |
亚当 | 琼斯 | 12/一月/16 |
布拉德 | 史密斯 | 01/十二月/16 |
凯莉 | 约翰逊 | 01/十二月/16 14:08:25 |
你可以看到输出类似于我们之前看到的。
我们可以用许多不同的方式输出它。
SELECT first_name, last_name,
TO_CHAR(date_of_birth, 'DD MONTH YY HH:MI:SS AM') AS date_output
FROM student;
名字 | 姓氏 | 出生日期 |
亚当 | 琼斯 | 12 一月 16 12:00:00 上午 |
布拉德 | 史密斯 | 01 十二月 16 12:00:00 上午 |
凯莉 | 约翰逊 | 01 十二月 16 02:08:25 下午 |
所以,你明白了。你可以使用 TO_DATE
函数插入 DATE
和 DATE TIME
值。你可以直接从表中读取值,或者通过更改 session
参数或使用 TO_CHAR
函数来格式化它们以包含时间。