Question

I am working with SQL via IBM's iNavigator. I have the following query:

SELECT
PWGEOADDR AS ADDRESS,
POSSTR(PWGEOADDR, ' ')-1 AS FIRSTWORDCHARS,
SUBSTR(PWGEOADDR, 1, POSSTR(PWGEOADDR, ' ')-1) AS HOUSECHAR,
INTEGER(SUBSTR(PWGEOADDR, 1, POSSTR(PWGEOADDR, ' ')-1)) AS HOUSENUMBER
FROM DSDLIB.PWPPERMITS

In my results pane, I see results like this:

ADDRESS                 FIRSTWORDCHARS   HOUSECHAR             HOUSENUMBER
----------------------------------------------------------------------------
1730 West 800 South    4                 1730                           1730
273 E Heather Road     3                 273                             273
56 N State Street      2                 56                               56
2080 S. Main           4                 2080                           2080
Across Oakcrest Dr.    6                 Across               ++++++++++++++
123 North Main         3                 123                             123

The + characters are literal characters I see in the SQL window. I copied and pasted them as-is.

My problem is this: I cannot query ADDRESS records that have a HOUSENUMBER in a given range, such as BETWEEN 30 AND 50. I want to ignore rows that cannot be successfully cast. Whenever I add a WHERE statement that compares the result of the CAST to ANYTHING, I get the following error from the AS/400:

SQL State: 22023

Vendor Code: -802

Message: [SQL0802] Data conversion or data mapping error. 
Cause . . . . . :   Error type 6 has occurred. 

Error types and their meanings are:

1 -- Arithmetic overflow. 

2 -- Floating point overflow. 

3 -- Floating point underflow. 

4 -- Floating point conversion error. 

5 -- Not an exact result. 

6 -- Numeric data that is not valid. 

7 -- Double-byte character set (DBCS) or UTF-8 data that is not valid. 

8 -- Division by zero. 

9 -- Hash value cannot be computed for the requested query. 

10 -- User-defined function returned a mapping error. 

11 -- Not valid length found in a varying-length column returned from an array result set. 

12 -- Result of a concatenation operation on a varying-length field exceeded the maximum allowed length of the result type. If the error occurred when assigning a value to a host variable of a FETCH, embedded SELECT, SET, or VALUES INTO statement, the host variable name is *N and the relative position of the host variable in the INTO clause is 0. If the host variable name is *N, the error occurred when attempting to resolve a search condition. If more than one data mapping error occurred, this is a description of the first error that occurred.  For a description of any other data mapping errors, see the previously listed messages in the job log. Recovery  . . . :   The error was caused by data that was not valid or that was too large.  Look at the previously listed messages in the job log (DSPJOBLOG command) or press F10 (Display messages in job log) on this display to determine what row and columns were involved in the error.  Correct the data and then try the request again.

What I've already tried is comparing the CAST against NULL, SNAN, INFINITY, and ++++++++++++++.

Was it helpful?

Solution

I think the following will work. This tests to see if the first word is a number by eliminating the numbers in the word (using translate()) and checking the length of the string. The result is then turned into an integer:

SELECT PWGEOADDR AS ADDRESS, POSSTR(PWGEOADDR, ' ')-1 AS FIRSTWORDCHARS,
       SUBSTR(PWGEOADDR, 1, POSSTR(PWGEOADDR, ' ')-1) AS HOUSECHAR,
       (case when LENGTH(RTRIM(TRANSLATE(SUBSTR(PWGEOADDR, 1, POSSTR(PWGEOADDR, ' ')-1), '*', '0123456789'))) = 0
             then INTEGER(SUBSTR(PWGEOADDR, 1, POSSTR(PWGEOADDR, ' ')-1))
        end) AS HOUSENUMBER
FROM DSDLIB.PWPPERMITS;

For use in a where clause, you would want to make this a subquery:

select t.*
from (SELECT PWGEOADDR AS ADDRESS, POSSTR(PWGEOADDR, ' ')-1 AS FIRSTWORDCHARS,
             SUBSTR(PWGEOADDR, 1, POSSTR(PWGEOADDR, ' ')-1) AS HOUSECHAR,
             (case when LENGTH(RTRIM(TRANSLATE(SUBSTR(PWGEOADDR, 1, POSSTR(PWGEOADDR, ' ')-1), '*', '0123456789'))) = 0
                   then INTEGER(SUBSTR(PWGEOADDR, 1, POSSTR(PWGEOADDR, ' ')-1))
              end) AS HOUSENUMBER
      FROM DSDLIB.PWPPERMITS
     ) t
where housenumber between 10 and 15;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top