【问题标题】:Stored Procedure - Error When Converting Date存储过程 - 转换日期时出错
【发布时间】:2017-10-24 16:28:46
【问题描述】:

我的存储过程失败,我正在尝试将时间戳转换为日期。

create or replace PROCEDURE "USP_CLEAN_FOBTPP" 
AS
BEGIN
  INSERT INTO CLN_FOBTPP
    SELECT PART_PAYMENT_ID,
           ISSUING_SHOP,
           TILL_NUMBER,
           SLIP_NUMBER,
           FOBT_NUMBER,
           WHO_PAID,
           to_date(WHEN_PAID,'DD-MON-YY HH24:MI:SS'),
           AMOUNT_LEFT_TO_PAY,
           FOBT_VALUE,
           STATUS
      FROM IMPORTDB.IMP_FOBTPP;
   COMMIT;
END;

这是我得到的错误:

ORA-01830: 日期格式图片在转换整个输入之前结束 字符串。

这是When_Paid日期列的格式

11-OCT-17 13.29.20.000000000
11-OCT-17 13.30.21.000000000
11-OCT-17 13.31.11.000000000
11-OCT-17 12.56.39.000000000
11-OCT-17 12.57.28.000000000
11-OCT-17 12.57.46.000000000

出了什么问题?

Source Table IMPORTDB.IMP_FOBT
Name               Null? Type         
------------------ ----- ------------ 
PART_PAYMENT_ID          NUMBER(38)   
ISSUING_SHOP             CHAR(4)      
TILL_NUMBER              NUMBER(3)    
SLIP_NUMBER              NUMBER(38)   
FOBT_NUMBER              VARCHAR2(30) 
WHO_PAID                 CHAR(20)     
WHEN_PAID                TIMESTAMP(6) 
AMOUNT_LEFT_TO_PAY       NUMBER(19,4) 
FOBT_VALUE               NUMBER(19,4) 
STATUS                   CHAR(2)      

Destination Table IMPORTDB.CLN_FOBTPP
Name               Null?    Type         
------------------ -------- ------------ 
PART_PAYMENT_ID    NOT NULL VARCHAR2(4)  
ISSUING_SHOP       NOT NULL VARCHAR2(4)  
TILL_NUMBER        NOT NULL NUMBER(3)    
SLIP_NUMBER        NOT NULL VARCHAR2(4)  
FOBT_NUMBER        NOT NULL VARCHAR2(30) 
WHO_PAID           NOT NULL CHAR(20)     
WHEN_PAID          NOT NULL DATE         
AMOUNT_LEFT_TO_PAY NOT NULL NUMBER(19,4) 
FOBT_VALUE         NOT NULL NUMBER(19,4) 
STATUS             NOT NULL CHAR(2)     

这是表结构。

【问题讨论】:

  • WHEN_PAID 列的数据类型是什么?如果它是date(看起来是这样),那就离开它,不要应用to_date()函数,否则它会通过双重转换:date -> character -> back to date。在这种情况下,各种 NLS 参数的值开始发挥作用NLS_DATE_FORMAT, NLS_LANGUGAE, NLS_TERRITORY
  • When_Paid 的数据类型是源表中的 Timestamp,我要加载数据的表中的日期。
  • 我已经包含了表定义。
  • 真是巧合!我刚刚听到一位同事迟到了,因为他被困在解决同样的 ORA 错误中
  • 哈哈,我是 PL-SQL 和 oracle 的新手,但这让我很困惑接下来要尝试什么。

标签: oracle function stored-procedures


【解决方案1】:

如果存储的数据是timestamp数据类型,你需要的是CAST,而不是TO_DATE

...
, cast (when_paid as date) , ...

编辑:在此答案下方的评论中,OP 说他收到一个错误,关于小时必须在 1 到 12 之间。不确定 OP 做错了什么;为了证明 Oracle 中的 cast 函数不是这种情况,这里有一个说明:

with input (ts) as (
  select to_timestamp('11-OCT-17 15:35:24.000000000', 'dd-MON-rr hh24:mi:ss.ff')
  from   dual
)
select ts, cast(ts as date) as dt
from   input;

TS                            DT
----------------------------  -------------------
11-OCT-17 15.35.24.000000000  2017-10-11 15:35:24

【讨论】:

  • 那么我应该使用 cast 函数吗?
  • cast(WHEN_PAID 作为日期),我剩下 ORA-01849:小时必须在 1 到 12 之间
  • @J.Doe - 我不是在那里看着你的肩膀看看你在做什么。我刚刚编辑了答案以表明cast 没有超过 12 小时的问题。我相信你并没有完全分享你在做什么。
【解决方案2】:

您正在尝试将 TIMESTAMP 列与 TO_DATE 转换为插入到 DATE 列中 - 这不是必需的。这完美无缺。

create table source1 ( t TIMESTAMP );

create table dest1 ( t DATE );
INSERT INTO source1 VALUES(SYSTIMESTAMP);

INSERT INTO dest1 SELECT * FROM source1;

PS:把这行to_date(WHEN_PAID,'DD-MON-YY HH24:MI:SS')改成WHEN_PAID,

【讨论】:

  • 这看起来不错,但是如何修改我的存储过程以包含它?
  • 另外,总是包含一个INTO 子句,所有列的顺序与select 相同,以避免混淆
  • 虽然这是一个糟糕的做法。如果您输入时间戳并输出日期,Oracle 会为您进行隐式转换,但最好是显式编码这些转换。
  • 创建或替换 PROCEDURE "USP_CLEAN_FOBTPP" AS BEGIN INSERT INTO CLN_FOBTPP SELECT PART_PAYMENT_ID, ISSUING_SHOP, TILL_NUMBER, SLIP_NUMBER, FOBT_NUMBER, WHO_PAID, WHEN_PAID, AMOUNT_LEFT_TO_PAY, FOBT_VALUE, STATUS FROM IMPORT犯罪;结束;
  • 11/10/2017 11/10/2017 11/10/2017 11/10/2017 11/10/2017 11/10/2017 11/10/2017 11/10/2017 11/ 2017 年 10 月 2017 年 11 月 10 日 2017 年 11 月 10 日 2017 年 11 月 10 日
猜你喜欢
  • 2018-09-30
  • 2014-09-07
  • 2017-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多