ORA-01858 while executing created procedure - oracle

I have created a procedure to find a date between today and expiry_date.
The table column format is already in date format.
While creating procedure it is created successfully without errors but during execution of procedure as below it is showing
ORA-01858: a non-numeric character was found where a numeric was expected
ALTER SESSION SET NLS_DATE_FORMAT ='dd-mm-yyyy';
CREATE OR REPLACE PROCEDURE flow (
today IN DATE,
expiry_date IN DATE
) AS
BEGIN
FOR rec in (
SELECT *
FROM flow4
WHERE englishcalendar BETWEEN 'englishcalendar.today'
AND 'englishcalendar.expiry_date')
LOOP
dbms_output.put_line(rec.englishcalendar);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(sqlerrm);
END;
/
EXEC FLOW('01-02-2017','03-04-2018');
/
I had also tried adding to_date in both procedure and procedure execution but i got same error
I also tried with this reference too
Getting Error - ORA-01858: a non-numeric character was found where a numeric was expected
NOTE englishcalendar contains continuous day of 2019 in 'dd-mm-yyyy' date format

'englishcalendar.today' is a string not a date. Likewise 'englishcalendar.expiry_date'. Oracle is attempting to convert these strings to dates and failing, because they are not dates.
Simple solution: reference the parameters as identifiers not strings:
...
FOR rec in (
SELECT *
FROM flow4
WHERE englishcalendar BETWEEN today
AND expiry_date)
...

Related

Converting an Oracle Stored Procedure DATE Input Parameter

I am very new to Oracle and have a question about input parameters to a stored procedure. Basically its a stored procedure being called from an external system passing in a date formatted as MM/DD/YYYY.
Oracle doesn't seem to like the MM/DD/YYYY format as it gives me a "not a valid month" error. (I think it wants like a DD-MMM-YYYY?) whatever the default is.
is there a way to convert the date as it comes into the procedure without getting an error?
such as:
create procedure test_proc
(
v_input_date IN DATE := to_char(v_input_date, 'MM/DD/YYYY')
)
I know the above code likely makes no actual sense but hopefully it will convey what I'd like to do. The user would call the procedure something like
BEGIN
test_proc('01/01/2018')
END
You may try with ANSI type date 'yyyy-mm-dd' formatting like in the following sample :
SQL>create or replace procedure test_proc( v_input_date date ) is
v_diff int;
begin
v_diff := trunc(sysdate)-v_input_date;
dbms_output.put_line(v_diff||' days difference...');
end;
/
SQL> set serveroutput on;
SQL> begin
test_proc(date '2018-03-21');
end;
/
2 days difference...
Your problem is not in the procedure, it is in the code calling the procedure.
'01/01/2018' is not a date it is a string but your procedure expects a date; however, Oracle tries to be helpful and will implicitly try to convert the string to a date using the TO_DATE( string_value, format_model ) function. Since it does not have a specified format model, it will use the default format for a date which is the NLS_DATE_FORMAT session parameter and if this format mask does not match the format of the string then you will get an error.
(Note: session parameters are per-user-session and can be changed by each user so you should not rely on them being the same for each user or even the same between sessions for the same user!)
You can see the format of the NLS_DATE_FORMAT session parameter using the query:
SELECT VALUE
FROM NLS_SESSION_PARAMETERS
WHERE PARAMETER = 'NLS_DATE_FORMAT';
And your code to call the procedure is implicitly being converted to something like:
BEGIN
test_proc(
TO_DATE(
'01/01/2018',
( SELECT VALUE FROM NLS_SESSION_PARAMETERS WHERE PARAMETER = 'NLS_DATE_FORMAT' )
)
);
END;
To generate a date you should explicitly convert the string to a date either by:
Using an ANSI literal
BEGIN
test_proc( DATE '2018-01-01' );
END;
Or by specifying the format mask used in the conversion
BEGIN
test_proc( TO_DATE( '01/01/2018', 'MM/DD/YYYY' ) );
END;

oracle stored procedure using date parameter

Is it possible to use a date parameter for a stored procedure?
for example, date 20171201 I need to execute a case A in a dateparameter.prc
and date 20171202 execute a case B in a dateparameter.prc which is the same procedure above.
I am googling and investigating some books but I still haven't found a solution.
Can anyone know about it?
Thanks
Yes, it is possible.
SQL> set serveroutput on
SQL> create procedure dt_demo(p_d date) as
2 begin
3 dbms_output.put_line('p_d = ' || p_d);
4 end;
5 /
Procedure created
SQL> exec dt_demo(date '2017-12-02');
p_d = 02.12.17
PL/SQL procedure successfully completed
Is it possible to use a date parameter for a stored procedure?
Yes. A simple example that takes a date as an IN date parameter and passes it directly to an OUT date parameter is:
CREATE PROCEDURE your_procedure(
in_value IN DATE,
out_return OUT DATE
)
IS
BEGIN
out_return := in_value;
END;
/
Your procedure is functioning correctly. But
The expression "DATE '2017-12-02'" represents the ISO date standard.
The expression "dbms_output.put_line('p_d = ' || p_d)" represents the regular Oracle date processing, which precedes the ISO specification.
How the date is formatted (displayed) during dbms_ouput converts the date to a string. Since in this case there is an implicit conversion the resulting format is controlled by the NLS_DATA_FORMAT setting. It looks like yours is set to "dd-mm-yy". To see the difference insert/run the following before your exec statement:
alter session set nls_date_format = 'yyyy-mm-dd" ;
Also see Oracle Date Format for Oracle 11g or as appropriate for your version.

PL/SQL insert date with procedure

I want to insert date in my dates table by passing date as ('19-JUN-1997') parameter to procedure. Could anyone give me an example how to do it? It seems that I am doing something wrong with trying to insert date by putting variable in TO_DATE(my_var).
SET SERVEROUTPUT ON
BEGIN
p_date('14-MAR-2017');
END;
CREATE OR REPLACE PROCEDURE p_date(
v_date IN Dates.date1%type) IS
BEGIN
INSERT INTO Dates
(date1)
VALUES
(TO_DATE(v_date ));
END;
If you know the format of the date (e.g., dd-mon-yyyy) then the safest thing to do is make your insert statement like thus:
INSERT INTO Dates (date1)
VALUES (TO_DATE(v_date, 'DD-MON-YYYY');
In order for your example to work, the character string date format must be in the default date format in the database. You can get the value of the database default format using this:
SELECT value
FROM nls_session_parameters
WHERE parameter = 'NLS_DATE_FORMAT'
However, if the default format is changed and you are relying on it, your code will break. It also tells the reader of the code what the date format you're expecting is.

Formatting Date Error - Oracle 11g

Trying to write a SQL query to format a date output, but I am getting an error stating, 'a non-numeric character was found where a numeric is expected.'
Below is my SQL:
SELECT e.emp_num, emp_lname, emp_fname, sal_amount
FROM LGEMPLOYEE e
JOIN LGSALARY_HISTORY sh ON e.emp_num = sh.emp_num
WHERE sal_from = (SELECT MIN (to_date(sal_from,'dd-mon-yy'))
FROM LGSALARY_HISTORY sh
WHERE sh.emp_num = e.emp_num)
ORDER BY e.emp_num;
Can anyone help to resolve this issue?
Try to replace
MIN (to_date(sal_from,'dd-mon-yy'))
with
TO_CHAR(MIN (to_date(sal_from,'dd-mon-yy')), 'dd-mon-yy')
You're trying to compare VARCHAR2 with a DATE. Oracle uses an implicit types conversation using the following rule:
When comparing a character value with a DATE value, Oracle converts
the character data to DATE.
Just an assumption: Oracle is trying to convert sal_from to a DATE using default NLS settings (session or database) and apparently fails (because the default date format is 'dd-mm-yy' for example)
This is why it's never a good idea to store date values in a varchar2 column. There is at least one row in your table where the character string in sal_from isn't in the format you expect. That's causing the to_date call to throw an error.
One way of isolating the problematic rows would be something like
CREATE OR REPLACE FUNCTION is_valid( p_str IN VARCHAR2, p_mask IN VARCHAR2 )
RETURN VARCHAR2
IS
l_date DATE;
BEGIN
l_date := to_date( p_str, p_mask );
RETURN 'Y';
EXCEPTION
WHEN others THEN
RETURN 'N';
END;
and then
SELECT *
FROM lgsalary_history
WHERE is_valid( sal_from, 'dd-mon-yy' ) = 'N'

ORA-12714: invalid national character set specified

I got a problem with oracle database ,i created a stored procedure and i wanted to pass an array of items' ids to this procedure to select the data according to array of items using "in" clause,the available solution to this as i found was to create a function and pass a string value with all item's ids seperated by a comma ,and this function will return a datatble with a row for each item id.this approach works fine when i try it in toad in a select statement,,but when i use it in the stored procedure i get a strange error
"ORA-12714: invalid national character set specified"
after searching about the reason of that error i found that it is a bug in that version of oracle according to this page and it was fixed in a 10.2.0.4 oracle patch and the exact reason is to declare a cursor for the function that returns a data table
As it is impossible to me to let the users who work on a live production environment to stop the servers to apply the update patch ,I was wondering if any Oracle expert can help me to declare a cursor and return that cursor instead of returning the table.
my Oracle function,Thanks in Advance
create or replace
FUNCTION SplitIDs(
v_List IN VARCHAR2)
RETURN RtnValue_Set PIPELINED
AS
SWV_List VARCHAR2(2000);
v_RtnValue Dt_RtnValue := Dt_RtnValue(NULL);
BEGIN
SWV_List := v_List;
WHILE (instr(SWV_List,',') > 0)
LOOP
FOR RetRow IN
(SELECT ltrim(rtrim(SUBSTR(SWV_List,1,instr(SWV_List,',') -1))) SelectedValue
FROM dual
)
LOOP
v_RtnValue.SelectedValue := RetRow.SelectedValue;
PIPE ROW(v_RtnValue);
END LOOP;
SWV_List := SUBSTR(SWV_List,instr(SWV_List,',')+LENGTH(','),LENGTH(SWV_List));
END LOOP;
FOR RetRow IN
(SELECT ltrim(rtrim(SWV_List)) SelectedValue FROM dual
)
LOOP
v_RtnValue.SelectedValue := RetRow.SelectedValue;
PIPE ROW(v_RtnValue);
END LOOP;
RETURN;
END;
Oracle says this about the error:
Error: ORA-12714 (ORA-12714)
Text: invalid national character set specified
Cause: Only UTF8 and AL16UTF16 are allowed to be used as the national character set
Action: Ensure that the specified national character set is valid
Check your NLS_NCHAR_CHARACTERSET which is set using:
select value from NLS_DATABASE_PARAMETERS where parameter = 'NLS_NCHAR_CHARACTERSET';
Try using NCHAR, NVARCHAR2 or NCLOB

Resources