I found this odd behavior and I'm breaking my brains with this... anyone has any ideas?
Oracle 10g: I have two different tables, both have this column named "TESTCOL" as Varchar2(10), not nullable.
If I perform this query on table1, i get the proper results:
select * from table1 where TESTCOL = 1234;
Note that I'm specifically not placing '1234'... it's not a typo, that's a dynamic generated query and I will try not to change it (at least not in the near future).
But, if I run the same query, on table2, I get this error message:
ORA-01722: Invalid number
Both queries are run on the same session, same database.
I've been joining these two tables by that column and the join works ok, the only problem shows whenever I try to use that condition.
Any ideas on what could be different from one table to the other?
Thanks in advance.
To check whether a text string is a number, ie whether it contains only valid number characters, you can use the following syntax with the IsNumber function: IsNumber(<text value>) <text value> is a number.
To convert a varchar type to a numeric type, change the target type as numeric or BIGNUMERIC as shown in the example below: SELECT CAST('344' AS NUMERIC) AS NUMERIC; SELECT CAST('344' AS BIGNUMERIC) AS big_numeric; The queries above should return the specified value converted to numeric and big numeric.
The CHAR and VARCHAR2 datatypes store alphanumeric data. Character data is stored in strings, with byte values corresponding to the character encoding scheme (generally called a character set or code page). The database's character set is established when you create the database, and never changes.
TO_NUMBER converts expr to a value of NUMBER datatype. The expr can be a BINARY_FLOAT or BINARY_DOUBLE value or a value of CHAR , VARCHAR2 , NCHAR , or NVARCHAR2 datatype containing a number in the format specified by the optional format model fmt .
If TESTCOL
contains non-numbers, then Oracle might run into problems when converting TESTCOL
entries to numbers. Because, what it does internally, is this:
select * from table1 where TO_NUMBER(TESTCOL) = 1234;
If you're so sure that 1234
cannot be expressed as a VARCHAR
literal, then try this instead, in order to compare varchar values, rather than numeric ones:
select * from table1 where TESTCOL = TO_CHAR(1234);
Well obvious TABLE2.TESTCOL contains values which are not numbers. Comparing a string to a numeric literal generates an implicit conversion. So any value in TESTCOL hich cannot be cast to a number will hurl ORA-1722.
It doesn't hit you where you compare the two tables because you are comparing strings.
So you have a couple of options, neiher of which you will like. The most obvious answer is to clean the data so TABLE2 hdoesn't contain non-numerics. Ideally you should combine this with changing the column to a numeric data type. Otherwise you can alter the generator so it produces code you can run against a shonky data model. In this case that means wrapping literals in quote marks if the mapped column has a character data type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With