I am creating a procedure for which I collect data by repeatedly running the following query.
SELECT ATTRIBUTE_VALUE,
COUNT(src1) CNT1,
COUNT(src2) CNT2
FROM (
SELECT a.ATTRIBUTE_VALUE,
1 src1,
TO_NUMBER(NULL) src2
FROM (
SELECT DECODE(
L,
1, IP_ADDRESS,
DECODE(
L,
2, IP_SUBNET_MASK,
DECODE(
L,
3, IP_DEFAULT_GATEWAY
)
)
) ATTRIBUTE_VALUE
FROM ( SELECT LEVEL L FROM DUAL X CONNECT BY LEVEL <= 3 ),
REUT_LOAD_IP_ADDRESSES
WHERE LIP_IPT_NAME = 'CE'
AND IP_LNT_ID IN (
SELECT LNT_ID
FROM REUT_LOAD_NTN
WHERE LNT_ID IN (
SELECT RLPN.LPN_LNT_ID
FROM REUT_LOAD_PI_NTN RLPN
WHERE LPN_LPI_ID IN (
SELECT RLPI.LPI_ID
FROM REUT_LOAD_PAC_INS RLPI
WHERE RLPI.LPI_DATE_ADDED IN (
SELECT MAX(RLPI2.LPI_DATE_ADDED)
FROM REUT_LOAD_PAC_INS RLPI2
WHERE RLPI2.PI_JOB_ID = P_ORDER_ID
)
)
)
AND IP_CEASE_DATE IS NULL
AND LNT_SERVICE_INSTANCE = 'PRIMARY'
)
It is running fine in SQL developer but when executing it as a procedure, I am getting INVALID NUMBER ERROR (ORA-01722: invalid number) at
AND IP_LNT_ID IN ( SELECT LNT_ID
, in the code. Can I get any help?
The error is pretty clear. You're comparing a number to another type of value.
Example:
SELECT 'x'
FROM DUAL
WHERE 1 IN (SELECT 'a'
FROM DUAL)
This means that IP_LNT_ID
, LNT_ID
, LPN_LNT_ID
and LPI_ID
have to be NUMBER
. And LPI_DATE_ADDED
and LPI_DATE_ADDED
should both be date or timestamp.
If this is not possible you could compare everything as char
:
SELECT ATTRIBUTE_VALUE, COUNT(src1) CNT1, COUNT(src2) CNT2
FROM (SELECT a.ATTRIBUTE_VALUE, 1 src1, TO_NUMBER(NULL) src2
FROM (SELECT
DECODE(L,1,IP_ADDRESS,DECODE(L,2,IP_SUBNET_MASK,DECODE(L,3,IP_DEFAULT_GATEWAY) ) ) ATTRIBUTE_VALUE
FROM
(
SELECT LEVEL L FROM DUAL X CONNECT BY LEVEL <= 3
),
REUT_LOAD_IP_ADDRESSES
WHERE LIP_IPT_NAME = 'CE'
AND to_char(IP_LNT_ID) IN (
SELECT LNT_ID
FROM REUT_LOAD_NTN
WHERE to_char(LNT_ID) IN (
SELECT RLPN.LPN_LNT_ID
FROM REUT_LOAD_PI_NTN RLPN
WHERE to_char(LPN_LPI_ID) IN (
SELECT RLPI.LPI_ID
FROM REUT_LOAD_PAC_INS RLPI
WHERE to_char(RLPI.LPI_DATE_ADDED) IN (
SELECT MAX(RLPI2.LPI_DATE_ADDED)
FROM REUT_LOAD_PAC_INS RLPI2
WHERE RLPI2.PI_JOB_ID = P_ORDER_ID
)
)
)
AND IP_CEASE_DATE IS NULL
AND LNT_SERVICE_INSTANCE = 'PRIMARY'
)
But this should be avoided on any cost. Unfortunately some times we have to cheat a little from time to time to work with our existing infrasructure ;-)
You need to make sure:
REUT_LOAD_IP_ADDRESSES.IP_LNT_ID
and
REUT_LOAD_NTN.LNT_ID
Have the same data type or cast/convert one or other so that they have the same data type.
There are multiple other issues:
You have aggregated and non-aggregated values:
SELECT ATTRIBUTE_VALUE, COUNT(src1) CNT1, COUNT(src2) CNT2 FROM ( ... )
Without a GROUP BY
clause.
src2
is TO_NUMBER(NULL)
which is just NULL
and COUNT(NULL)
will always be 0
so your query is:
SELECT ATTRIBUTE_VALUE, COUNT(src1) CNT1, 0 CNT2 ...
This code:
SELECT DECODE( L, 1, IP_ADDRESS, DECODE( L, 2, IP_SUBNET_MASK, DECODE( L, 3, IP_DEFAULT_GATEWAY ) ) ) ATTRIBUTE_VALUE FROM ( SELECT LEVEL L FROM DUAL X CONNECT BY LEVEL <= 3 ), REUT_LOAD_IP_ADDRESSES
Can be rewritten as:
SELECT DECODE( L, 1, IP_ADDRESS, 2, IP_SUBNET_MASK, 3, IP_DEFAULT_GATEWAY ) ATTRIBUTE_VALUE FROM ( SELECT LEVEL L FROM DUAL X CONNECT BY LEVEL <= 3 ), REUT_LOAD_IP_ADDRESSES
Or, without the join as:
SELECT attribute_value FROM REUT_LOAD_IP_ADDRESSES UNPIVOT ( attribute_value FOR L IN ( IP_ADDRESS AS 1, IP_SUBNET_MASK AS 2, IP_DEFAULT_GATEWAY AS 3 ) )
The innermost query:
SELECT RLPI.LPI_ID FROM REUT_LOAD_PAC_INS RLPI WHERE RLPI.LPI_DATE_ADDED IN ( SELECT MAX(RLPI2.LPI_DATE_ADDED) FROM REUT_LOAD_PAC_INS RLPI2 WHERE RLPI2.PI_JOB_ID = P_ORDER_ID )
The inner query is restricted to have RLPI2.PI_JOB_ID = P_ORDER_ID
but there is no correlation between the outer query so you can retrieve results that do not match P_ORDER_ID
but just happen to have the same date as a matching row.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.