If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

 
Go Back  dBforums > Database Server Software > DB2 > Case Statement problem

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 06-27-11, 11:59
teel teel is offline
Registered User
 
Join Date: Jun 2011
Posts: 13
Case Statement problem

I am writing a SQL query in DB2 for a report that contains a case statement to pull matching strings from two tables. The case statement is below:

CASE
WHEN LEFT( t1.stringfield,7) = LEFT(t2.stringfield,7) THEN substr(t2.stringfield,1,7)

WHEN SUBSTR(t1.stringfield,3,7) = SUBSTR(t2.stringfield,8,12) THEN SUBSTR(t2.stringfield,6,12)

ELSE ' '
END AS Derive

the first 7 characters and the 3rd character to 7 of table 't1.stringfield' has a matching characters in table 't2.stringfield' in the 8th and 6th place of table 't2.stringfield' the string. I am getting an error as shown below :

Failed to retrieve data from Database
SQL0138N A numeric argument of a bulit-in string function is out of range SLQSTATE = 22011



I dont know what other function can I use to extract string from the middle of a string field. I tried using left(right( in place of substr, but they dont pull out the the exact locations of the string. Please, Any help will be appreciated
Reply With Quote
  #2 (permalink)  
Old 06-27-11, 13:21
n_i n_i is offline
:-)
 
Join Date: Jun 2003
Location: Toronto, Canada
Posts: 4,449
It might mean that some of the strings are shorter than you think.
Code:
C:\>db2 values substr('abc',1,1)

1
-
a

  1 record(s) selected.


C:\>db2 values substr('abc',1,10)
SQL0138N  A numeric argument of a built-in string function is out of range.
SQLSTATE=22011

C:\>db2 values substr('abc',10,1)
SQL0138N  A numeric argument of a built-in string function is out of range.
SQLSTATE=22011
Reply With Quote
  #3 (permalink)  
Old 06-27-11, 13:50
tonkuma tonkuma is online now
Registered User
 
Join Date: Feb 2008
Location: Japan
Posts: 2,193
Quote:
WHEN SUBSTR(t1.stringfield,3,7) = SUBSTR(t2.stringfield,8,12) THEN SUBSTR(t2.stringfield,6,12)
You might misunderstand the third parameter of SUBSTR built-in function.
It is the length of the returned string.
So, you might want to code...
WHEN SUBSTR(t1.stringfield,3,5) = SUBSTR(t2.stringfield,8,5) THEN SUBSTR(t2.stringfield,6,7)
Reply With Quote
  #4 (permalink)  
Old 06-28-11, 11:16
teel teel is offline
Registered User
 
Join Date: Jun 2011
Posts: 13
Case statement problem

Thanks for the reply, but there are millions of records in the stringfield and the length of the characters differ from row to row, some have 12 characters, some have 7 and so on, so what function in DB2 would be able to handle variable character lengths in a stringfield, besides substr?
Reply With Quote
  #5 (permalink)  
Old 06-28-11, 12:19
n_i n_i is offline
:-)
 
Join Date: Jun 2003
Location: Toronto, Canada
Posts: 4,449
Something like
Code:
WHEN 
 LENGTH(t1.stringfield) >= 10 AND 
 LENGTH(t2.stringfield) >= 20 AND 
 SUBSTR(t1.stringfield,3,7) = SUBSTR(t2.stringfield,8,12) 
THEN SUBSTR(t2.stringfield,6,12) ...
Reply With Quote
  #6 (permalink)  
Old 06-28-11, 13:32
teel teel is offline
Registered User
 
Join Date: Jun 2011
Posts: 13
Case statement problem

Thanks buddy ! Let me try it out.
Reply With Quote
  #7 (permalink)  
Old 06-28-11, 15:12
teel teel is offline
Registered User
 
Join Date: Jun 2011
Posts: 13
Case statement problem

Quote:
Originally Posted by n_i View Post
Something like
Code:
WHEN 
 LENGTH(t1.stringfield) >= 10 AND 
 LENGTH(t2.stringfield) >= 20 AND 
 SUBSTR(t1.stringfield,3,7) = SUBSTR(t2.stringfield,8,12) 
THEN SUBSTR(t2.stringfield,6,12) ...

I tried using that method above but I get the same error as before.

Failed to retrieve data from the database SQL0138N A numeric argument of a built-in function is out of range SQLSTATE=22011
Reply With Quote
  #8 (permalink)  
Old 06-28-11, 15:33
n_i n_i is offline
:-)
 
Join Date: Jun 2003
Location: Toronto, Canada
Posts: 4,449
I'm sure you have adjusted the LENGTH() comparison values according to the actual lengths of your strings. The point is to short-circuit the boolean expression before it gets to the SUBSTR() part.
Reply With Quote
  #9 (permalink)  
Old 06-28-11, 15:36
teel teel is offline
Registered User
 
Join Date: Jun 2011
Posts: 13
c

ohh ok. let me check on that. Thanks!
Reply With Quote
  #10 (permalink)  
Old 06-28-11, 15:38
n_i n_i is offline
:-)
 
Join Date: Jun 2003
Location: Toronto, Canada
Posts: 4,449
It also matters if the column datatype is VARCHAR or CHAR. LENGTH() of a CHAR column will always be the same, while that of VARCHAR will vary according to the actual value length.
Reply With Quote
  #11 (permalink)  
Old 06-28-11, 16:32
teel teel is offline
Registered User
 
Join Date: Jun 2011
Posts: 13
Case statement problem

I think the string is varchar because looking through the records, the actual lengths are different for different rows, the lengths are not fixed.
Reply With Quote
  #12 (permalink)  
Old 06-28-11, 19:56
tonkuma tonkuma is online now
Registered User
 
Join Date: Feb 2008
Location: Japan
Posts: 2,193
Please show the result of this query,
if you have not solved yet your problem.

Code:
SELECT LENGTH(t1.stringfield) AS len_str_1
     , LENGTH(t2.stringfield) AS len_str_2
     , COUNT(*)               AS count_rows
 FROM  t1
 JOIN  t2
   ON  <matching conditions>
 GROUP BY
       LENGTH(t1.stringfield)
     , LENGTH(t2.stringfield)
 ORDER BY
       len_str_1
     , len_str_2
;

Last edited by tonkuma; 06-29-11 at 01:17. Reason: Add "if you have not solved yet your problem."
Reply With Quote
  #13 (permalink)  
Old 06-29-11, 02:02
Peter.Vanroose Peter.Vanroose is offline
Registered User
 
Join Date: Sep 2004
Location: Belgium
Posts: 1,079
Whhat you also could do (if the outcome of this is fine for you) is first pad the input data with blanks before taking substrings:
Code:
CASE
WHEN LEFT( t1.stringfield||'       ',7) = LEFT(t2.stringfield||'       ',7)
 THEN substr(t2.stringfield,1,7)
WHEN SUBSTR(t1.stringfield||'        ',3,5)
      = SUBSTR(t2.stringfield||'            ',8,5)
 THEN SUBSTR(t2.stringfield,6,7)
ELSE ' '
END AS Derive
__________________
--_Peter Vanroose,
__IBM Certified Database Administrator, DB2 9 for z/OS
__IBM Certified Application Developer
__ABIS Training and Consulting
__http://www.abis.be/
Reply With Quote
  #14 (permalink)  
Old 06-29-11, 08:49
teel teel is offline
Registered User
 
Join Date: Jun 2011
Posts: 13
Case statement problem

Quote:
Originally Posted by tonkuma View Post
Please show the result of this query,
if you have not solved yet your problem.

Code:
SELECT LENGTH(t1.stringfield) AS len_str_1
     , LENGTH(t2.stringfield) AS len_str_2
     , COUNT(*)               AS count_rows
 FROM  t1
 JOIN  t2
   ON  <matching conditions>
 GROUP BY
       LENGTH(t1.stringfield)
     , LENGTH(t2.stringfield)
 ORDER BY
       len_str_1
     , len_str_2
;


Thanks. Here is a sample of the result set:

len_str_1 | len_str_2 | Count_Rows

7 | 1 | 33
7 | 4 | 688
7 | 5 | 258
7 | 6 | 265
7 | 7 | 13901
7 | 8 | 1158
7 | 9 | 336
7 | 10 | 654
7 | 12 | 851
Reply With Quote
  #15 (permalink)  
Old 06-29-11, 11:00
tonkuma tonkuma is online now
Registered User
 
Join Date: Feb 2008
Location: Japan
Posts: 2,193
Looking into your data,
length of t1.stringfield were fixed to 7
and maximun length of t2.stringfield was 12.

If those were guaranteed
(for example: data type of t1.stringfield was CHAR(7) and data type of t2.stringfield was VARCHAR(12).)
then, try...
Code:
CASE
WHEN t1.stringfield            = LEFT (t2.stringfield , 7) THEN
     t1.stringfield
WHEN LENGTH(t2.stringfield) = 12
 AND RIGHT(t1.stringfield , 5) = RIGHT(t2.stringfield , 5) THEN
     RIGHT(t2.stringfield , 7)
ELSE ' '
END  AS Derive
It returns 7 character string when matched on first WHEN clause.
(if t2.stringfield was shorter than 7, padded with blanks)

What DB2 version and platform are you using?
If you are using older version, data type of returned value may be long.
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On