简体   繁体   中英

PL/SQL: Invalid Number error

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:

  1. You have aggregated and non-aggregated values:

     SELECT ATTRIBUTE_VALUE, COUNT(src1) CNT1, COUNT(src2) CNT2 FROM ( ... ) 

    Without a GROUP BY clause.

  2. 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 ... 
  3. 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 ) ) 
  4. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM