ORACLE中date类型字段的处理

ORACLE中date类型字段的处理

(1)在英文版本的ORACLE中默认日期格式为'DD-MON-YY', 例如'01-JAN-98'

  在汉化的中文版本中ORACLE默认日期格式为'日-月-年',例如'21-8月-2003'或'21-8月-03'

(2) 转换字符串为日期
使用ORACLE内部函数to_date
()

to_date()函数的参数是to_char()函数参数的反转。

to_date(string_value , date_format)

变量定义如下:

string_value :为字符串直接值(字符串本身)、字符串列(数据库中定义的某个表的某列)或某字符串内部函数的返回值。

date_format为合法的Oracle日期格式。

下列更新语句均符合ORACLE的日期格式,更新成功:

create table student (name varchar2(10) not null primary key , enrolldate date not null);//创建student表

insert into student values('mark',to_date('08-21-2003','MM-DD-YYYY'));

 

insert into student values('mark1',to_date('21-08-2003','DD-MM-YYYY'));

 

insert into student values('mark2','21-8月-2003');

 

insert into xiongxiaomin.student values('mark3','21-8月-03');

(3) 转换日期为字符串
使用ORACLE内部函数to_char
()
to_char(date_value,date_format

变量定义如下:

date_value :为日期型直接值(日期本身)、日期型列值(数据库中定义的某个表的某列)或某内部函数的返回的日期型值。

date_format为合法的Oracle日期格式。

 

选择enrolldate字段的时间部分:

select (to_char(enrolldate,'HH24:MI:SS'))enrolldate from  student;

 
(4)注意:ORACLE中的date
数据类型定义的列包含日期和时间。

1、系统当前日期为2003年8月21,之后执行下列语句

insert into student values('mark5',to_date('09:28:03','HH:MI:SS'));//注意此种在一条记录的date类型字段中插入时间的方法,系统默认的日期为系统当前日期所在月份的第一天,因此得到的记录为

 

Name            enrolldate

 

mark5    01-八月 -2003 09:28:03 AM

 

2、修改系统当前日期为2003年7月21,之后执行下列语句

insert into student values('mark6',to_date('09:28:03','HH:MI:SS'));

得到的记录为

Name            enrolldate

 

mark6     01-七月 -2003 09:28:03 AM

 

insert into student values('mark8',to_date('20:28:03','HH24:MI:SS'));

 
3
、同时在一条记录中插入日期和时间的方法

insert into student values('mark9',to_date('21-08-2003

20:28:03','DD-MM-YYYY HH24:MI:SS'));//同时在一条记录中插入日期和时间的方法

 

insert into student values('mark',to_date('21-08-2003

09:52:03','DD-MM-YYYY HH:MI:SS'));//同时在一条记录中插入日期和时间的方法

 
注意不能使用下列方法同时插入日期和时间

insert into student values('mark2','21-8月-2003'+to_date('

09:52:03','HH:MI:SS'));//无效插入记录方法

 
4、在SQL*Plus Worksheet中执行下列SQL
语句

select * from student;

得到的记录结果如下:注意date类型字段中只显示了日期,时间并未显示

NAME                 ENROLLDATE

 

mark               18-8月 -03

mark1              21-8月 -03

mark2              21-8月 -03

 

 

 

已选择3行。

 
 
 
 

5、但在JSP程序中同样执行select * from student order by enrolldate

显示结果见下图(既显示了日期,又显示了时间

 

                         JSP页面中的显示结果

6、在SQL*Plus Worksheet中执行下列SQL 语句

select name,to_char(enrolldate,'DD-MM-YYYY HH:MI:SS') from student;

得到的记录结果如下:注意date类型字段中显示了日期和时间

NAME                 TO_CHAR(ENROLLDATE,'DD-MM-YYYYHH:MI:SS

mark               21-08-2003 12:00:00

mark1              21-08-2003 12:00:00


已选择2行

注意:5和6中的不同,时间到秒时,JSP页面中显示时多出了". 0 "
7、在SQL*Plus Worksheet中执行下列SQL
语句

select name,to_char(enrolldate,'DD-MM-YYYY HH24:MI:SS') from student;

得到的记录结果如下:注意date类型字段中显示了日期,时间

NAME                 TO_CHAR(ENROLLDATE,'DD-MM-YYYYHH24:MI:

 

mark               18-08-2003 17:40:20

mark1              21-08-2003 00:00:00

mark2              21-08-2003 00:00:00


已选择3行。

注意:6和7中的SELECT中的"HH:MI:SS"和"HH24:MI:SS"两者的不同是"HH"为小时制,值的范围为0-12;"HH24"为24小时制,值的范围为0-23。

   看下列例子:

①insert into student values('南太里',to_date('08-19-2003
13:54:05','MM-DD-YYYY HH24:MI:SS'));
ORACLE中的记录结果为:
NAME                   enrolldate
南太里                19-八月 -2003 01:54:05 PM
②insert into student values('南太里2',to_date('08-19-2003
13:54:05','MM-DD-YYYY HH:MI:SS'));//插入错误
错误提示为:

insert into student values('南太里2',to_date('08-19-2003 13:54:05','MM-DD

                                                          *

ERROR 位于第 1 行:

ORA-01849: 小时值必须介于 1 和 12 之间

即应用"HH"时,不能应用"13:54:05",而应改为"01:54:05"

正确语句如下:

insert into student values('南太里2',to_date('08-19-2003

01:54:05','MM-DD-YYYY HH:MI:SS'));

ORACLE中的记录结果为:
NAME                   enrolldate

南太里2              19-八月 -2003 01:54:05 AM
注意上述两种方式得出的结果一种为PM,另一种为AM。

为了提高正确性,建议都是用地一种方式"HH24"

8、但在JSP程序中同样执行select name,to_char(enrolldate,'DD-MM-YYYY HH:MI:SS') from student

显示结果见下图。(其结果与在SQL*Plus Worksheet中执行下列SQL语句

select name,to_char(enrolldate,'DD-MM-YYYY HH:MI:SS') from student;相同)

9、在SQL*Plus Worksheet中执行下列SQL 语句

select name,to_char(enrolldate,'month dd,yyyy HH24:MI:SS') from student;

得到的记录结果如下:注意date类型字段中显示了日期,时间

NAME                 TO_CHAR(ENROLLDATE,'MONTHDD,YYYYHH24:MI:SS')

 

mark               8月  18,2003 17:40:20

mark1              8月  21,2003 00:00:00

mark2              8月  21,2003 00:00:00


已选择3行。

10、to_char()函数,'DD-MM-YYYY'格式及'MM-DD-YYYY'格式和'month dd,yyyy' 格式的不同

'DD-MM-YYYY'格式:21-08-2003

'month dd,yyyy'格式:8月  21,2003

 

11、注意:在日期和时间格式中非常容易混淆的是月份和秒的格式(MM和MI

在SQLPlus*Worksheet中执行下列语句,不报错。

insert into student values('王嘉',to_date('08:05','HH24:MM'));//08被认为是小时,05被认为是月份。

commit;

在表编辑器中查看:实际插入值为

NAME                 ENROLLDATE

王嘉    01-五月 -2003 08:00:00 AM


select name,to_char(enrolldate,'DD-MM-YYYY HH24:MI:SS')enrolldate from

student where name='王嘉';


NAME                 ENROLLDATE

王嘉                 01-05-2003 08:00:00


已选择 1 行。


insert into student values('汪嘉2',to_date('08-19-2003

13:54:05','MM-DD-YYYY HH24:MI:SS'));

 
 

12、使用Oracle的date数据类型的另一个优点是:它支持日期的运算。可以对已经存在的

 

日期加上或减去若干天,例如:

insert into student values('熊',sysdate+7);

转载于:https://www.cnblogs.com/quechao123/archive/2009/09/11/2346711.html

<think>我们正在处理一个Oracle数据库插入数据时遇到的日期字段空值错误问题。根据用户描述,错误发生在向DATE类型字段插入空值(NULL)时。在Oracle中,向DATE字段插入NULL值本身是允许的,前提是字段没有非空约束(NOTNULLconstraint)。因此,错误可能源于:1.该字段有NOTNULL约束,但尝试插入NULL。2.插入的值虽然意图是NULL,但实际写成了字符串'NULL'(注意:字符串'NULL'和NULL是不同的)。3.使用了不正确的空值表示方法,例如在SQL语句中直接写入了"NULL"字符串而没有正确使用绑定变量或转换。解决方案:1.检查表结构,确认该DATE字段是否允许为NULL。-如果字段不允许为NULL,则不能插入NULL值。此时需要根据业务逻辑决定:要么插入一个有效的日期,要么修改表结构允许该字段为NULL(如果业务允许)。2.在INSERT语句中,如果要插入NULL,应该使用NULL关键字,而不是字符串'NULL'。例如:INSERTINTOtable_name(date_column)VALUES(NULL);或者,如果使用变量绑定,在编程语言中传递DBNull.Value(如C#)或null(如Java)等。3.如果从外部数据源(如文本文件)导入数据,空字符串可能被当作空值,但Oracle不会自动将空字符串转换为NULL(对于日期字段)。因此,需要在导入过程中将空字符串转换为NULL。4.使用Oracle的批量导入工具(如SQL*Loader、DataPump、或应用中的ETL工具)时,注意空值的处理方式。参考引用[2]中提到Oracle没有UPDATEFROM语法,但这里的问题是关于插入NULL到DATE字段。不过,引用[3]中提到了一个使用DBLINK的问题,虽然不直接相关,但提醒我们注意数据源的问题。因此,我们给出以下步骤:步骤1:确认表结构使用以下SQL查看表结构,特别是目标DATE字段的约束:SELECTcolumn_name,nullableFROMall_tab_columnsWHEREtable_name='YOUR_TABLE_NAME'ANDcolumn_name='YOUR_COLUMN_NAME';注意:表名和列名需要大写,除非创建时用了引号。步骤2:检查INSERT语句确保在INSERT语句中插入NULL值的方式正确。步骤3:处理外部数据源如果数据来自外部(如CSV文件),在导入时转换空字符串为NULL。例如,使用SQL*Loader的ctl文件可以指定:date_column"TO_DATE(:date_column,'YYYY-MM-DD')",NULLIFdate_column=BLANKS或者使用CASE语句在SQL中转换:INSERTINTOtable_name(date_column)VALUES(CASEWHENinput_value=''THENNULLELSETO_DATE(input_value,'格式')END);步骤4:使用NVL函数或DEFAULT值如果字段不允许为NULL,但业务上允许默认值,可以在INSERT语句中使用NVL函数或DEFAULT关键字。INSERTINTOtable_name(date_column)VALUES(NVL(?,SYSDATE));--如果传入空则用当前日期--或者INSERTINTOtable_name(date_column)VALUES(DEFAULT);--如果字段有默认值步骤5:修改表结构(如果必要)如果确认该字段可以接受NULL值,但当前约束不允许,可以修改表结构:ALTERTABLEtable_nameMODIFY(date_columnNULL);注意:修改表结构需要谨慎,特别是生产环境。如果上述步骤仍不能解决问题,请提供具体的错误信息(如ORA-XXXXX)和插入语句的示例,以便进一步分析。生成相关问题:1.如何检查Oracle表中某字段是否允许为空?2.Oracle中如何将空字符串转换为NULL?3.在Oracle中插入数据时,如何为DATE类型字段设置默认值?4.在PL/SQL中如何处理NULL值插入?5.使用SQL*Loader导入数据时如何处理空日期字段?</think>### Oracle处理 DATE 类型字段插入空值错误 在 Oracle 数据库中向 `DATE` 类型字段插入空值时出现错误,通常由以下原因及解决方案导致: --- #### **1. 检查字段约束** - **问题**:若字段定义为 `NOT NULL`,尝试插入 `NULL` 会触发错误。 - **解决方案**: ```sql -- 查看字段约束 SELECT column_name, nullable FROM all_tab_columns WHERE table_name = 'YOUR_TABLE' AND column_name = 'DATE_COLUMN'; ``` - 若 `nullable = 'N'`,需修改约束或提供默认值: ```sql ALTER TABLE your_table MODIFY (date_column NULL); ``` --- #### **2. 正确插入 NULL 值** - **问题**:错误语法(如 `'NULL'` 字符串)会导致类型不匹配。 - **解决方案**: - **直接插入 NULL**: ```sql INSERT INTO your_table (date_column) VALUES (NULL); ``` - **使用绑定变量**(编程语言示例): ```java // Java 示例 PreparedStatement stmt = conn.prepareStatement("INSERT INTO your_table (date_column) VALUES (?)"); stmt.setNull(1, Types.DATE); // 显式设置 NULL ``` --- #### **3. 外部数据源处理** - **问题**:从文件或 API 导入时,空字符串未转换为 `NULL`。 - **解决方案**: - **SQL*Loader 控制文件**: ```sql LOAD DATA INFILE 'data.csv' INTO TABLE your_table FIELDS TERMINATED BY ',' (date_column "TO_DATE(:date_column, 'YYYY-MM-DD')" NULLIF date_column=BLANKS) ``` - **应用层转换**(Python 示例): ```python # 插入前转换空字符串为 None data = [None if x == '' else x for x in csv_data] cursor.execute("INSERT INTO table VALUES (:1)", [data]) ``` --- #### **4. 使用默认值替代 NULL** 若业务允许空值,但字段有 `NOT NULL` 约束: ```sql -- 方案1:设置默认值 ALTER TABLE your_table MODIFY date_column DEFAULT SYSDATE; -- 方案2:插入时动态处理 INSERT INTO your_table (date_column) VALUES (COALESCE(?, SYSDATE)); -- 绑定变量为空时使用当前日期 ``` --- #### **5. 验证 DBLINK 问题** 若通过 DBLINK 跨库操作(如引用[3]场景): ```sql -- 重建 DBLINK 后测试 INSERT INTO remote_table@dblink (date_column) SELECT NULL FROM dual; -- 显式测试 NULL 插入 ``` 若仍失败,建议改用本地临时表中转数据[^3]。 --- ### 相关问题 1. 如何批量修改 Oracle 表中多个字段的 `NULL` 约束? 2. 在 PL/SQL 中如何动态处理不同数据类型的空值插入? 3. 使用 Oracle Data Pump 导入数据时如何处理空日期字段? 4. Oracle 中 `DATE` 与 `TIMESTAMP` 类型对空值的处理有何差异? 5. 如何监控和记录插入空值时的数据库错误(如 ORA-01857)? [^1]: 引用[1]: 解决方案: 使用Oracle Integration Cloud (OIC) 或 Oracle API Manager 来创建和管理API,确保数据的实时同步和一致性。此外,可以利用Oracle ERP Cloud的Data Loader工具进行批量数据导入,减少数据处理时间。 [^2]: 引用[2]: —update Oracle没有update from语法,可以通过两种写法实现同样的功能: 1:子查询UPDATE A SET A.NAME=(SELECT B.NAME FROM B WHERE B.ID=A.ID),本查询要根据具体情况看看是否变通成如下 (1)单列 UPDATE A。 [^3]: 引用[3]: 开发怀疑有可能是 DBLINK 导致的问题,所以重建了 DBLINK,不幸的是,重建后依然报错。后面索性直接不使用 DBLINK,改为在本地建一张表,然后直接在本地插入数据,确实可行,数据库没有再报错,产线也恢复正常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值