01858

siv3szwd  于 2021-08-13  发布在  Java
关注(0)|答案(2)|浏览(348)

我知道这个问题以前已经回答过了,我也尝试过他们给出的解决方案,但没有成功。
我有一个存储过程,如下所示(我删除了非必要的部分):

CREATE OR REPLACE PROCEDURE get_days(dt date)
IS
  given_date DATE := TO_DATE('dt', 'DD-MON-YYYY');
BEGIN
  get_day := RTRIM(TO_CHAR(dt1, 'DAY'));
  DBMS_OUTPUT.PUT_LINE ('The day of the given date is '||get_day||);
  DBMS_OUTPUT.PUT_LINE ('Execution  done successfully.');
END get_days;

我在把日期传递到程序上有困难 get_days . 我试过以下几种方法:

BEGIN
  --Below I have listed all ways I have tried 
  get_days('12/12/12');
  get_days('12-12-12');
  get_days(date '2012-12-12');  
  get_days(TO_DATE( '01/01/2018', 'MM/DD/YYYY' ));
END;

我不知道怎么了,但我得到了这个错误- ORA-01858: a non-numeric character was found where a numeric was expected . 我曾在网上搜索过类似的错误,但没有任何帮助。我使用的是oracle database 11g速成版。我的代码中可能有一些小错误,但我不知道它是什么。
非常感谢您的帮助!

ttisahbt

ttisahbt1#

错误的直接原因是

given_date DATE := TO_DATE('dt', 'DD-MON-YYYY');

而不是

given_date DATE := TO_DATE(dt, 'DD-MON-YYYY');

在您的版本中,您试图转换字符串文字 'dt' 约会;这个文字跟你的 dt 争论。
然而,这仍然是错误的,因为 dt 已声明为日期数据类型。如果你这么做,那么你真的在做:

given_date DATE := TO_DATE(TO_CHAR(dt), 'DD-MON-YYYY');

哪个将使用当前会话 NLS_DATE_FORMAT 将日期转换为字符串;如果这不是'dd mon yyyy'(或者某个足够接近的东西,oracle会捏造它),那么您仍然会得到一个错误,或者更糟糕的是,不正确的转换和无效的结果,您可能不会注意到。
因此,移除冗余和危险的转换:

CREATE OR REPLACE PROCEDURE get_days(dt date)
IS
BEGIN
  DBMS_OUTPUT.PUT_LINE ('The day of the given date is ' || TO_CHAR(dt, 'FMDAY') || '.');
  DBMS_OUTPUT.PUT_LINE ('Execution  done successfully.');
END get_days;
/

当然,如果需要的话,可以将日名称指定给字符串变量。我用过 FM 格式修饰符,以阻止它右填充日期名称,所以你不需要修剪它-句号只是在那里证明它的工作。如果你想在混合大小写你可以使用一天的名称 'FMDay' 而不是 'FMDAY' .
您应该始终传递日期,而不是字符串:

set serveroutput on;

BEGIN
  get_days(date '2012-12-12');  
  get_days(TO_DATE( '01/01/2018', 'MM/DD/YYYY' ));
END;
/

The day of the given date is WEDNESDAY.
Execution  done successfully.
The day of the given date is MONDAY.
Execution  done successfully.

PL/SQL procedure successfully completed.

dt可以以任何格式传递。我只是把它转换成dd-mm-yyyy格式并存储到给定的\u日期
日期没有格式;它有一个你很少需要知道或关心的内在表征。当查询日期值而不显式地将其转换为字符串时,客户机通常使用 NLS_DATE_FORMAT 决定以何种格式显示。所以呢 dt 没有格式,即使调用方使用字符串进行调用(如前两个示例所示),这些字符串也将在调用之前隐式转换为日期(假设可能);这个过程永远不会看到那些字符串,它只会看到转换后的日期值。

hsvhsicv

hsvhsicv2#

我提供了最好的答案来解决有关这个程序的问题。你也可以自己运行来检查

DECLARE

dt1 DATE := TO_DATE(TO_CHAR('19/03/2021'), 'DD-MM-YYYY');

get_day VARCHAR2(15);

BEGIN
get_day := RTRIM(TO_CHAR(dt1, 'DAY'));

IF get_day IN ('SATURDAY', 'SUNDAY') THEN
dbms_output.new_line;
DBMS_OUTPUT.PUT_LINE 
('The day of the given date is '||get_day||' and it falls on weekend');

ELSE
dbms_output.new_line;
DBMS_OUTPUT.PUT_LINE ('The day of the given date is '||get_day||' and it does not fall 
on the weekend');

END IF;
DBMS_OUTPUT.PUT_LINE ('Execution  done successfully.');
END;

如果您对此有任何进一步的疑问,请询问我,我会尽快解决您的疑问。如果有人想输入用户的日期,请问我…我也有这个代码。

相关问题