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文字与格式字符串不匹配”。
请建议,我们如何解决错误?
感谢。
答案 0 :(得分:1)
由于这一行:
p_due_date := to_char(p_due_date,'yyyy-mm-dd');
你得到这个错误。
由于p_due_date是date
,而分配产生char
。
顺便说一下,由于,
中的r,due_days
答案 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);
代替。
祝你好运。