ORA-01861文字与存储过程中的格式字符串错误不匹配

时间:2017-10-10 17:24:06

标签: sql oracle plsql

Hello Experts,

我们要求根据emp_id

找到截止日期

    create table emp_test (emp_id number, customer_due_date date)
    /
    create table dept_test (due_days number)
    /
    insert into emp_test values (1,sysdate)
    /
    insert into emp_test values (2,sysdate-1)
    /
    insert into emp_test values (3,sysdate-2)
    /
    insert into emp_test values (4,sysdate+1)
    /
    insert into emp_test values (5,sysdate+2)
    /
    insert into dept_test values(2)
    /
    commit
    /

我的存储过程:

    create or replace procedure test_proc(p_emp_id in emp_test.emp_id%type,p_due_date out date)
    as
    begin
    select
    (case
    when trim(to_char(trunc(o.customer_due_date) - r,due_days, 'Day')) = 'Sunday' then trunc(o.customer_due_date)-r.due_days-2
    when trim(to_char(trunc(o.customer_due_date) - r.due_days,
    'Day')) = 'Saturday' then trunc(o.customer_due_date)-r.due_days-1
    when trunc(o.customer_due_date) is null then trunc(sysdate) + 60
    else trunc(o.customer_due_date) - r.due_days
    end
    ) Due_date
    into p_due_date
    from
    dept_test r,
    emp_test o
    where o.emp_id = p_emp_id;

    p_due_date := to_char(p_due_date,'yyyy-mm-dd');

    end;

我收到错误,因为“ORA-01861文字与格式字符串不匹配”。

请建议,我们如何解决错误?

感谢。

3 个答案:

答案 0 :(得分:1)

由于这一行:

 p_due_date := to_char(p_due_date,'yyyy-mm-dd');

你得到这个错误。

由于p_due_date是date,而分配产生char

顺便说一下,由于,中的r,due_days

,第6行程序也存在问题

答案 1 :(得分:1)

您正在使用数据类型快速而宽松地玩游戏。也许您的编程经验是使用/不强制执行数据类型的一种或多种语言。

在函数声明中,您说p_due_date将是DATE数据类型。但是当你第一次分配它(通过SELECT ... INTO)时,你会为它分配一个字符串。由于您没有将其包装在适当的TO_DATE函数中,因此Oracle(强制数据类型有时但并非总是如此,并且其许多猜测明显错误)尝试使用会话的p_due_date参数将字符串转换为分配给NLS_DATE_FORMAT之前的日期。如果那不是(通过某种意外)确切的'yyyy-mm-dd',你会得到这个错误。

执行此操作的正确方法是在CASE内的SELECT ... INTO语句中包含TO_DATE()表达式。

顺便说一下,在代码的后面你有TO_CHAR(.....) - 为什么你有这个,完全不清楚。 TO_CHAR会返回一个字符串,但您要分配回p_due_date,这必须是DATE,因此您有更多的隐式转换(使用错误的格式模型)。当然,如果您按照我的建议修复了SELECT ... INTO语句,则在选择p_due_date之后,您无需执行任何操作;你可以按原样归还。

答案 2 :(得分:0)

正如其他人所说的那样

p_due_date := to_char(p_due_date,'yyyy-mm-dd');

似乎是个问题。如果你要做的是删除日期值的时间部分,我建议你使用

p_due_date := TRUNC(p_due_date);

代替。

祝你好运。