Passing date to Stored Procedure in Oracle SQL error : ORA-01858
Passing date to Stored Procedure in Oracle SQL error : ORA-01858
我知道这个问题之前有人回答过,我也尝试过他们给出的解决方案,但没有成功。
我有一个存储过程如下(我删除了非必要部分):
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
。我在网上搜索过类似的错误,但 none 帮助了我。我正在使用 Oracle 数据库 11g 快捷版。我的代码中可能存在一些小错误,但我不明白是什么。
非常感谢任何帮助!
错误的直接原因是你有
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 将 fudge it 足够接近),那么您仍然会收到错误,或者更糟的是,您可能不会注意到不正确的转换和无效结果。
因此删除多余且危险的转换:
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;
/
如果需要,您当然可以将日期名称分配给字符串变量。我已经使用 the FM
format modifier 来阻止它向右填充日期名称,因此您不需要 trim 它 - 句号只是为了证明它有效。如果你想要混合大小写的日期名称,你可以使用 '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 might be passed in any format. I am just converting it into DD-MM-YYYY format and storing into given_date
日期没有格式;它有一个你很少需要知道或关心的内部表示。当您查询日期值而不明确将其转换为字符串时,您的客户端会将其转换为人类可读的形式,通常使用 NLS_DATE_FORMAT
来决定以何种格式显示它。因此 dt
没有一种格式,即使调用者使用字符串进行调用(如前两个示例所示),它们也会在调用之前隐式转换为日期 - 假设这是可能的;该过程永远不会看到那些字符串,它只会看到转换后的日期值。
我正在提供解决有关此程序的查询的最佳答案。也可以自己运行查看
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;
如果您对此有任何进一步的疑问,请问我,我会尽快解决您的疑问。
如果有人想按用户输入日期,请问我....我也有这方面的代码。
我知道这个问题之前有人回答过,我也尝试过他们给出的解决方案,但没有成功。
我有一个存储过程如下(我删除了非必要部分):
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
。我在网上搜索过类似的错误,但 none 帮助了我。我正在使用 Oracle 数据库 11g 快捷版。我的代码中可能存在一些小错误,但我不明白是什么。
非常感谢任何帮助!
错误的直接原因是你有
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 将 fudge it 足够接近),那么您仍然会收到错误,或者更糟的是,您可能不会注意到不正确的转换和无效结果。
因此删除多余且危险的转换:
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;
/
如果需要,您当然可以将日期名称分配给字符串变量。我已经使用 the FM
format modifier 来阻止它向右填充日期名称,因此您不需要 trim 它 - 句号只是为了证明它有效。如果你想要混合大小写的日期名称,你可以使用 '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 might be passed in any format. I am just converting it into DD-MM-YYYY format and storing into given_date
日期没有格式;它有一个你很少需要知道或关心的内部表示。当您查询日期值而不明确将其转换为字符串时,您的客户端会将其转换为人类可读的形式,通常使用 NLS_DATE_FORMAT
来决定以何种格式显示它。因此 dt
没有一种格式,即使调用者使用字符串进行调用(如前两个示例所示),它们也会在调用之前隐式转换为日期 - 假设这是可能的;该过程永远不会看到那些字符串,它只会看到转换后的日期值。
我正在提供解决有关此程序的查询的最佳答案。也可以自己运行查看
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;
如果您对此有任何进一步的疑问,请问我,我会尽快解决您的疑问。 如果有人想按用户输入日期,请问我....我也有这方面的代码。