oracle中往varchar2格式的字段中插入date时间格式的值会发生什么?

本文创建了一个名为TEST1的表,其中TDATE字段为VARCHAR2类型,并尝试插入日期格式的数据。在查询时,发现日期显示为不寻常格式(01-7月 -15)。为了解决这个问题,提供了SQL更新语句来转换TDATE字段的格式,将其从01-7月 -15格式转换为正常的YYYYMMDD格式。

 

--建立表test1

create table TEST1
(
  ID    VARCHAR2(40) default sys_guid(),
  TDATE VARCHAR2(200)
)
tablespace APP_TX_DATA
  pctfree 10
  pctused 40
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    minextents 1
    maxextents unlimited
  );

--插入date时间格式数据

insert into test1 values(sys_guid(),sysdate+10);、

--查询数据

select * from test1  -- tdate值为 01-7月 -15

--Q:如何将现有数据01-7月 -15格式刷成正常的YYYYMMDD格式?

update test1 t set t.tdate = '20'||substr(t.tdate,instr(t.tdate, '-', 1, 2) + 1,2)
       || case instr(t.tdate, '月', 1, 1) - (instr(t.tdate, '-', 1, 1) + 1)
          when 1 then '0' || substr(t.tdate,
                             instr(t.tdate, '-', 1, 1) + 1,
                             (instr(t.tdate, '月', 1, 1)) - (instr(t.tdate, '-', 1, 1) + 1))
          when 2 then substr(t.tdate,
                             instr(t.tdate, '-', 1, 1) + 1,
                             (instr(t.tdate, '月', 1, 1)) - (instr(t.tdate, '-', 1, 1) + 1))
          else t.tdate end
        || substr(t.tdate,0,2)
  where t.tdate like '%月%' order by t.tdate

 

### Oracle 中将 VARCHAR 类型转换为 DATE 类型的方法及 ORA-01861 错误解决 在 Oracle 数据库中,`VARCHAR2` 类型的数据可以通过 `TO_DATE` 函数显式转换为 `DATE` 类型。此过程需要指定明确的日期格式字符串以确保转换成功。如果格式不匹配,则会触发 `ORA-01861: 文字与格式字符串不匹配` 的错误。 #### 1. 使用 `TO_DATE` 函数进行显式转换 `TO_DATE` 函数允许用户定义输入字符串的日期格式,从而将其正确解析为 `DATE` 类型。例如: ```sql SELECT TO_DATE('2023-10-05', 'YYYY-MM-DD') FROM dual; ``` 上述语句将字符串 `'2023-10-05'` 转换为日期类型,其中 `'YYYY-MM-DD'` 是指定的日期格式[^4]。 #### 2. 确保日期格式一致 当从 `VARCHAR2` 转换到 `DATE` 类型时,必须确保输入字符串的格式与 `TO_DATE` 函数中的格式字符串完全匹配。例如,以下示例会导致 `ORA-01861` 错误,因为日期格式不匹配: ```sql SELECT TO_DATE('2023/10/05', 'YYYY-MM-DD') FROM dual; -- 错误示例 ``` 正确的写法应为: ```sql SELECT TO_DATE('2023/10/05', 'YYYY/MM/DD') FROM dual; -- 正确示例 ``` #### 3. 处理存储过程中可能出现的问题 在存储过程中,如果直接使用外部传入的 `VARCHAR2` 参数作为日期条件,可能会因未明确指定日期格式而导致 `ORA-01861` 错误。例如,在引用内容中提到的存储过程问题[^1],可以通过以下方式解决: ```sql CREATE OR REPLACE PROCEDURE p_bill_statics(start_date IN VARCHAR2, end_date IN VARCHAR2) IS v_start DATE := TO_DATE(start_date, 'YYYY-MM-DD'); -- 将输入参数转换为 DATE 类型 v_end DATE := TO_DATE(end_date, 'YYYY-MM-DD'); BEGIN SELECT COUNT(1) INTO v_cnt FROM t_receipt_data rd INNER JOIN t_account_info ac ON rd.account_code = ac.account_code INNER JOIN t_org_info oi ON ac.org_code = oi.org_code WHERE rd.type_code = v_type_cur.type_code AND ac.org_code = v_cur_init.org_code AND rd.import_time BETWEEN v_start AND v_end; -- 使用已转换的日期变量 END; ``` 通过在存储过程内部显式转换输入参数,可以避免因 NLS 设置或格式不匹配导致的错误。 #### 4. 检查默认的 NLS_DATE_FORMAT 设置 Oracle 数据库的 `NLS_DATE_FORMAT` 参数定义了默认的日期格式。如果未显式指定日期格式数据库将尝试根据此参数解析日期字符串。例如: ```sql ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'; -- 修改会话级别的日期格式 ``` 查询当前会话的日期格式设置: ```sql SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT'; ``` 如果发现默认格式与实际输入不匹配,建议始终使用 `TO_DATE` 函数显式指定日期格式[^3]。 #### 5. 示例:批量插入数据时的日期转换 在批量插入数据时,如果日期字段以字符串形式提供,必须使用 `TO_DATE` 函数进行转换。例如: ```sql INSERT ALL INTO Student (name, sex, age, address, birthday) VALUES ('Nike', '男', 18, '北京', TO_DATE('2000-01-01', 'YYYY-MM-DD')) INTO Student (name, sex, age, address, birthday) VALUES ('Nike', '女', 18, '北京', TO_DATE('2000-01-01', 'YYYY-MM-DD')) SELECT 1 FROM dual; ``` 上述语句中,`TO_DATE` 函数确保了日期字符串被正确解析为 `DATE` 类型[^4]。 --- ### 注意事项 - 始终显式指定日期格式,以避免因不同会话或环境下的 `NLS_DATE_FORMAT` 设置差异导致的错误。 - 在存储过程中处理日期参数时,推荐先将其转换为 `DATE` 类型再用于查询条件。 - 如果输入数据可能包含无效日期,可以使用异常处理机制捕获并记录错误。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值