简体   繁体   中英

Why doesn't Count work in my oracle sql

I am trying to do a count of items related to a person for my query, but I keep getting a

ORA-01722: invalid number
01722. 00000 -  "invalid number"
*Cause:    The specified number was invalid.
*Action:   Specify a valid number.

Here is my query:

    select distinct
    p.person_id as id,
    p.fullname as name, 
    p.email, 
    (select count(*) from ASSETS_MASTER m, PERSON p where m.asset_user = p.person_id) as Assets,
    p.last_updated
 from person p 
where p.deleted = 0
order by p.fullname asc;

the error is because of :

select count(*) from ASSETS_MASTER m, PERSON p where m.asset_user = p.person_id

in which case :

asset_user is datatype varchar2(255)

person_id is datatype number

but if I run

select asset_id from ASSETS_MASTER m, PERSON p where m.asset_user = p.person_id

this will show results of

CFRI1823m
5384w
CFRI5039
CFRI2319
CFRI5024
....

Can anyone tell me what I am getting this error?

To further illustrate the point I made in a Comment, which was:

We can't tell without seeing your data. Are you perhaps trying to compare a string ( m.asset_user ) with a number ( p.person_id ), or something of that nature?

Here is a similar example using the EMPLOYEES and DEPARTMENTS tables in the standard HR schema (which exists by default, after installation, on most Oracle systems):

select count(*) from hr.employees e, hr.departments d 
                where e.department_id = d.department_name;

ORA-01722: invalid number
01722. 00000 -  "invalid number"
*Cause:    The specified number was invalid.
*Action:   Specify a valid number.

Mathguy has an interesting explanation in the comments above. I don't know why you have your asset_user as VARCHAR if it is a number, and you might want to consider modifying the data type if you can. However, if it is possible to type convert to a number (ie your asset_user doesn't have values like AD34 ), you should be able to fix your query by doing this:

select count(*) from ASSETS_MASTER m, PERSON p 
where CAST(m.asset_user AS INT) = p.person_id

You can try this:

select count(*) from ASSETS_MASTER m, PERSON p where m.asset_user = '' || p.person_id

but it will prevent the use of the index of p.person_id in this case you'll have to create a functional index of to_char(person_id)

Answering your question directly - in your query Oracle implicitly calls to_number for varchar m.asset_user. It works fine until m.asset_user is assigned to something like '12345' or null or even ''... but once it meets something like '1 23' - it returns invalid number.

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