error invalid number ORA-01722 in Procedure [closed] - sql

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I have a procedure like below, but when I tried to running it using sqlplus its gave me error
BEGIN IB_ARCHIVE_FDS('FDS_LOG', 'TIME_REQUEST', 5, 6); END;
ERROR at line 1: ORA-01722: invalid number ORA-06512: at "NIAGA.IB_ARCHIVE_FDS", line 10 ORA-06512: at line 1
and I'm using Oracle 9i
CREATE OR replace PROCEDURE Ib_archive_fds(table_name VARCHAR2,
column_name VARCHAR2,
success_period NUMBER,
active_period NUMBER)
IS
TYPE fds_tabs
IS TABLE OF ib_fds_log%ROWTYPE INDEX BY PLS_INTEGER;
TYPE fds_message_id
IS TABLE OF ib_fds_log.message_id%TYPE INDEX BY PLS_INTEGER;
v_fds_log FDS_TABS;
v_message_id FDS_MESSAGE_ID;
BEGIN
SELECT *
bulk collect INTO v_fds_log
FROM ib_fds_log2
WHERE direction = 0
AND status_fds_message = 0
AND time_request < Trunc(SYSDATE - ' || SUCCESS_PERIOD || ' - 1);
FOR i IN 1 .. v_fds_log.last LOOP
V_message_id(i) := V_fds_log(i).message_id;
END LOOP;
forall indx IN 1 .. v_fds_log.count
INSERT INTO ib_fds_log3
VALUES V_fds_log(indx);
COMMIT;
forall indx IN 1 .. v_fds_log.count
DELETE FROM ib_fds_log2
WHERE message_id = V_message_id(indx);
COMMIT;
END;
can somebody help me to solve my problem here.

While I agree with David's analysis of the shortcomings of your implementation the actual cause of that error message is this bug:
time_request < trunc(sysdate - ' || SUCCESS_PERIOD || '- 1);
SUCCESS_PERIOD is a parameter and you presumably want to use it in your date calculation. However you have coded it as a string; a string is not a number and so we cannot use in in a substraction.
I'm not quite sure what arithmetic you're trying to achieve, but I think you want either this ...
time_request < trunc(sysdate - ( SUCCESS_PERIOD - 1));
... or this ...
time_request < trunc(sysdate - ( SUCCESS_PERIOD + 1) );
... depending on how you want to modify the value of SUCCESS_PERIOD.

This code should almost certainly avoid the cursors completely and just use SQL statements -- something along the lines of ...
procedure ib_archive_fds(
table_name varchar2,
column_name varchar2,
success_period number ,
active_period number )
is
time_request_limit date;
begin
time_request_limit := trunc(sysdate - success_period - 1)
insert into
ib_fds_log3
select
*
from
ib_fds_log2
where
direction = 0 and
status_fds_message = 0 and
time_request < ib_archive_fds.time_request_limit;
delete from
ib_fds_log2
where
direction = 0 and
status_fds_message = 0 and
time_request < ib_archive_fds.time_request_limit;
end;
Various enhancements would be possible if the result set of the query is not constant when this is executed, but all of the PL/SQL is just asking for errors and performance problems.

Related

Look up SDO_GEOMETRY validation error code using SQL

I have a query that validates an SDO_GEOMETRY in Oracle 18c:
select
sdo_geom.validate_geometry_with_context(
sdo_geometry ('polygon ((676832.320 4857578.086, 665287.423 4857578.086, 665277.423 4878109.585,
676832.320 4878119.585, 676842.320 4857588.086))', 26917)
, 0.005) as validation
from
dual
VALIDATION
-----------------------------
13348 [Element <1>] [Ring <1>]
(1 row selected.)
db<>fiddle
The query produces an error code in a text column, but it doesn't describe what the code means.
I am able look up the error manually in the docs: 82 ORA-12700 to ORA-19400
ORA-13348: polygon boundary is not closed
Cause: The boundary of a
polygon does not close.
Action: Alter the coordinate values or the
definition of the SDO_GTYPE or SDO_ETYPE attribute of the geometry.
But manually looking up those error codes is inconvenient.
Is there a way to enhance the query so that it returns the full error description? (get the description from the database)
Assuming you can parse the string to pull out the error message, you can pass it to sqlerrm to get the text of the error (note that you're apparently getting a positive value, you'd need to negate that value to pass it to sqlerrm). I would assume that you could just look for everything before the first space to get the error number but I don't have a huge sample set to work with.
declare
l_message varchar2(1000);
begin
l_message := sqlerrm( -13348 );
dbms_output.put_line( l_message );
end;
/
will print
ORA-13348: polygon boundary is not closed
Building on #JustinCave's answer, here's a custom function that gets the error description from the validation text:
with function error_description(validation in varchar2) return varchar2 is
begin
return sqlerrm(substr(validation, 1, instr(validation,' ') - 1) * -1); --Multiply by -1. Oracle error codes seem to be "negative".
end;
select
error_description(validation) as error_description
from
(select
sdo_geom.validate_geometry_with_context(
sdo_geometry ('polygon ((676832.320 4857578.086, 665287.423 4857578.086, 665277.423 4878109.585, 676832.320 4878119.585, 676842.320 4857588.086))', 26917), 0.005) as validation
from dual)
ERROR_DESCRIPTION
-------------------
ORA-13348: polygon boundary is not closed
Edit:
As pointed out by #SolomonYakobson in a related post, the SQLERRM() function can also be used in a SELECT query (without the need for a custom function).
Are certain kinds of Oracle functions only available in PL/SQL, not
SQL?
Many of the functions are defined in Oracle supplied package
SYS.STANDARD.
Example: SELECT SYS.STANDARD.SQLERRM(-1422) FROM DUAL;
So we just need to fully qualify the function: SYS.STANDARD.SQLERRM()
select
sys.standard.sqlerrm(substr(validation, 1, instr(validation,' ') - 1) * -1) error_description
from
(select
sdo_geom.validate_geometry_with_context(
sdo_geometry ('polygon ((676832.320 4857578.086, 665287.423 4857578.086, 665277.423 4878109.585, 676832.320 4878119.585, 676842.320 4857588.086))', 26917), 0.005) as validation
from dual)
ERROR_DESCRIPTION
---------------------
ORA-13348: polygon boundary is not closed

Oracle SQL - table type in cursor causing ORA-21700: object does not exist or is marked for delete

I have problem with my function, I'm getting ORA-21700: object does not exist or is marked for delete error. It's caused by table type parameter in cursor, but I've no idea how to fix it.
I've read that table type part should be assigned to a variable, but it can't be done in cursor, right? I've marked the part which causing the issue
Can anyone help? Is there any other way I can do this?
My package looks something like this:
FUNCTION createCSV(DateFrom date
,DateTo date)
RETURN clob IS
CURSOR c_id (c_DateFrom date
,c_DateTo date) IS
SELECT id
FROM limits
WHERE utcDateFrom <= NVL(c_DateTo, utcDateFrom)
AND NVL(utcDateTo, c_DateFrom + 1) >= c_DateFrom + 1;
CURSOR c (c_DateFrom date
,c_DateTo date
,pc_tDatePeriods test_pkg.t_date_periods) IS -- this is table type (TYPE xx AS TABLE OF records)
SELECT l.id limit_id
,TO_CHAR(time_cond.utcDateFrom, og_domain.cm_yyyymmddhh24mi) time_stamp_from
,TO_CHAR(time_cond.utcDateTo, og_domain.cm_yyyymmddhh24mi) time_stamp_to
FROM limits l
JOIN (SELECT limit_id, utcDateFrom, utcDateTo FROM TABLE(pc_tDatePeriods) --This part is causing the issue
) time_cond
ON l.id = time_cond.limit_id
WHERE l.utcDateFrom <= NVL(c_DateTo, l.utcDateFrom)
AND NVL(l.utcDateTo, c_DateFrom + 1) >= c_DateFrom + 1;
CSV clob;
tDatePeriods test_pkg.t_date_periods := test_pkg.t_date_periods();
BEGIN
FOR r_id IN c_id(DateFrom, DateTo)
LOOP
tDatePeriods := test_pkg.includeTimeGaps(p_Id => r_id.id); --this loop is ok
FOR r IN c(DateFrom, DateTo, tDatePeriods) --here I'm getting error
LOOP
CSV := CSV || chr(13) || r.limit_id || ',' || r.time_stamp_from || ',' || r.time_stamp_to;
END LOOP;
END LOOP;
RETURN CSV;
END createCSV;
Your problem should be solved by declaring type test_pkg.t_date_periods on schema level instead of in package.
Similar answer can be found here but with more details.

Error "Invalid Instruction" in PL/SQL function using Oracle

here i'm trying to create a sort of a boolean function but when i try to compile it, it says me that my instruction "truth INTEGER;" is not correct. I can't figure out where does the problem come from because every code sample that i've seen on Google is quite similar to mine. Using Oracle is totally new for me so i'm kinda lost if someone is okay to help me...
I tried a lot of things by searching but nothing works so i'm here to ask for some help...
CODE:
CREATE OR REPLACE FUNCTION HISTOTOX.matching_idipl (iDiplNumero INTEGER) RETURN INTEGER
AS
cpt INTEGER;
truth INTEGER;
BEGIN
SELECT count(*) INTO cpt FROM GARNUCHE.INSC_DIPL WHERE IDIPL_NUMERO = iDiplNumero;
IF cpt = 1 THEN
truth := 1;
ELSE
truth := 0;
END IF;
RETURN truth;
END;
What you reported isn't Oracle error. I replicated your code in my 11g and everything works just fine:
SQL> CREATE OR REPLACE FUNCTION matching_idipl (iDiplNumero INTEGER) RETURN INTEGER
2 AS
3 cpt INTEGER;
4 truth INTEGER;
5
6 BEGIN
7 SELECT count(*) INTO cpt FROM INSC_DIPL WHERE IDIPL_NUMERO = iDiplNumero;
8 IF cpt = 1 THEN
9 truth := 1;
10 ELSE
11 truth := 0;
12 END IF;
13 RETURN truth;
14 END;
15 /
Function created.
SQL> select matching_idipl(1) from dual;
MATCHING_IDIPL(1)
-----------------
1
SQL>
So: where exactly did you execute that code? Which error did you get (exact message and error code, please)?

PL/SQL and SQL Developer different results from each other

I am executing a query in PL / SQL in version 7 and version 14, with a function created by me, and both bring me some results, the rest bring 0.
However, when executing the same query in Oracle SQL Developer, the query brings all the results correctly.
I executed the procedure through PL / SQL and Oracle SQL Developer as well, but then none brought me the right result, all the lines were left as "0".
I can't find the problem at all, even on Google.
Basically, the function multiplies the number of rows by columns that start with "ID_", as shown below.
Function:
CREATE OR REPLACE FUNCTION DS_FUNCESP.FNBIGB_CheckDataCells
(pOwn IN VARCHAR2,
pTab IN VARCHAR2)
RETURN NUMBER
IS
v_Qtd NUMBER;
v_str VARCHAR2(2000);
BEGIN
v_Qtd := 1;
v_str := ' SELECT
SUM((SELECT COUNT(1) AS QTY_ROWS FROM ' || pOwn || '.' || pTab || ' d WHERE d.LINORIGEM <> ''CARGA MANUAL'')) AS QTY_DATA
FROM DW_FUNCESP.D_BI_COLUMNS a
LEFT JOIN
DW_FUNCESP.D_BI_TABLES b
ON a.ID_TABLE = b.ID_TABLE
AND a.ID_OWNER = b.ID_OWNER
LEFT JOIN DW_FUNCESP.D_BI_OWNERS c
ON a.ID_OWNER = c.ID_OWNER
WHERE b.NM_TABLE = ''' || pTab || '''
AND a.IN_PRIMARYKEY = ''NAO''
AND SUBSTR(a.NM_COLUMN,1,3) = ''ID_'' ';
DBMS_OUTPUT.put_line(v_str);
EXECUTE IMMEDIATE v_str into v_Qtd ;
return (v_Qtd);
EXCEPTION WHEN OTHERS THEN
RETURN 0;
END FNBIGB_CheckDataCells;
Select statement:
SELECT
c.NM_OWNER ,
b.NM_TABLE ,
DS_FUNCESP.FNBIGB_CHECKDATACELLS(c.NM_OWNER, b.NM_TABLE) AS QTY_DATA
FROM DW_FUNCESP.D_BI_TABLES b
LEFT JOIN DW_FUNCESP.D_BI_OWNERS c
ON b.ID_OWNER = c.ID_OWNER;
Results from PL/SQL:
Results from Oracle SQL Developer:
Clearly we can see the difference from any row, the right one is the Oracle SQL Developer. So I'd like to know what is the problem, how to fix, because the procedure is adding "0" to all the rows, no matter where I run.
Reading those examples from WHEN OTHERS - A Bug, thanks to #Lalit Kumar B for that, I changed:
EXCEPTION WHEN OTHERS THEN
RETURN 0;
To:
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('SQLCODE: '||SQLCODE);
DBMS_OUTPUT.PUT_LINE('Message: '||SQLERRM);
RAISE;
To find out the problem, and thanks for that I found that it was trying to count from a table where it doesn't exist anymore.
So I using an error handling as below, from #Jeffrey Kemp
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
RAISE;
END IF;
Also, thanks for #Belayer, my code was the problem, agreed on that. Also, executing on both softwares, made me even more confused. I'll read also that documentation for sure.

PLS-00306: wrong number or types of arguments in call to [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
Can anyone help me with this error. It works when I try the first procedure but not the second when I enter two numbers. Any ideas?
create or replace package LE2_P1
is
procedure GENERATE_MULTIPLICATION_TABLE(p_axis_both in number);
procedure GENERATE_MUTLIPLICATION_TABLE(p_axis_x in number, p_axis_y in number);
end LE2_P1;
/
create or replace package body LE2_P1
as
procedure GENERATE_MULTIPLICATION_TABLE(p_axis_both in number)
is
bb number := 1;
eb number := p_axis_both;
begin
for xyz in 1 .. eb loop
for xyx in 1 .. eb loop
dbms_output.put(CHR(9) || to_char(xyz * (bb + xyx - 1)));
end loop;
dbms_output.put_line(CHR(13) || CHR(10));
end loop;
end GENERATE_MULTIPLICATION_TABLE;
procedure GENERATE_MUTLIPLICATION_TABLE(p_axis_x in number, p_axis_y in number)
is
bb number := p_axis_x;
eb number:= p_axis_y;
begin
for xyz in 1 .. eb loop
for xyx in 1 .. eb loop
dbms_output.put(CHR(9) || to_char(xyz * (bb + xyx - 1)));
end loop;
dbms_output.put_line(CHR(13) || CHR(10));
end loop;
end GENERATE_MUTLIPLICATION_TABLE;
end LE2_P1;
/
declare
x number := 5;
y number := 3;
begin
LE2_P1.GENERATE_MULTIPLICATION_TABLE(x,y);
end;
/
The procedure with two arguments' name is typoed: MU T L IPLICATION
OracleParameter[] pr=new OracleParameter[20];
pr[1]=new OracleParameter("IN_BILL_COMPCD_C",OracleType.VarChar);
pr[1].Value=IN_BILL_COMPCD_C;
pr[1]=new OracleParameter("IN_BILL_BRCD_C",OracleType.VarChar);
pr[1].Value=IN_BILL_BRCD_C;
Two Parameter passed in single value. that's why arrive this error.