473,422 Members | 2,235 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,422 software developers and data experts.

Safe cast from string to integer

Hello,

I have a column of type VARCHAR, storing some generally character data.
A few of the values in that column are in fact numbers represented as
strings (e.g., "12345").

At some moment I need to select those numbers, cast them to INT and do
some math on them. Naturally, I do something like this:

SELECT INT(MYCOLUMN) WHERE I_BELIEVE_THIS_IS_A_NUMBER='true'

However, due to glitches in the logic that writes into MYCOLUMN,
sometimes it gets populated with values that are not castable to INT
(for example, a string with a carriage return in it). In that case, I
get -420 in my stored proc, and the query aborts.

What is the best way of rewriting a query like this to make sure that
it does not abort during execution? I am okay with INT(MYCOLUMN)
returning NULL on a dirty value.

I see several options, in order of decreasing preference:

1. Find a native DB2 casting function that would be tolerant of bad
charaters (could not find one so far).

2. Write a UDF that'll essentially only take digits from an input
string, and then convert that to INT.

I am going to fix the logic that writes into MYCOLUMN, to do my best to
have only values castable to INT. However, I'd like to see if may be
there's a function for 1) above, or if someone sees a better solution.

Thanks
Bogdan Sheptunov

Dec 5 '05 #1
7 52390
kangaroo wrote:
Hello,

I have a column of type VARCHAR, storing some generally character data.
A few of the values in that column are in fact numbers represented as
strings (e.g., "12345").

At some moment I need to select those numbers, cast them to INT and do
some math on them. Naturally, I do something like this:

SELECT INT(MYCOLUMN) WHERE I_BELIEVE_THIS_IS_A_NUMBER='true'

However, due to glitches in the logic that writes into MYCOLUMN,
sometimes it gets populated with values that are not castable to INT
(for example, a string with a carriage return in it). In that case, I
get -420 in my stored proc, and the query aborts.

What is the best way of rewriting a query like this to make sure that
it does not abort during execution? I am okay with INT(MYCOLUMN)
returning NULL on a dirty value.

I see several options, in order of decreasing preference:

1. Find a native DB2 casting function that would be tolerant of bad
charaters (could not find one so far).

2. Write a UDF that'll essentially only take digits from an input
string, and then convert that to INT.

I am going to fix the logic that writes into MYCOLUMN, to do my best to
have only values castable to INT. However, I'd like to see if may be
there's a function for 1) above, or if someone sees a better solution.

Thanks
Bogdan Sheptunov

Of the top I can only think of one way (short of parsing yourself):

db2 -td@

CREATE PROCEDURE friendlycast(IN txt VARCHAR(20), OUT num INTEGER)
CONTAINS SQL DETERMINISTIC NO EXTERNAL ACTION
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE 22018
BEGIN
SET num = NULL;
END;
num = INTEGER(txt);
END
@

CREATE FUNCTION friendlycast(txt VARCHAR)
RETURNS INTEGER
CONTAINS SQL DETERMINISTIC NO EXTERNAL ACTION
BEGIN ATOMIC
DECLARE num INTEGER;
CALL friendlycast(txt, num);
RETURN num;
END
@

That should do it (untested). Don't expect this to break any speed
records. Consider it punishement for lack of data cleansing ;-)

Cheers
Serge
--
Serge Rielau
DB2 SQL Compiler Development
IBM Toronto Lab
Dec 5 '05 #2
aj
I have the same sort of issue, and use this:

CREATE FUNCTION GETNUMBER(p_input VARCHAR(50))
RETURNS Integer
LANGUAGE SQL
CONTAINS SQL
DETERMINISTIC
NO EXTERNAL ACTION
RETURN
CASE WHEN
REPLACE(TRANSLATE(p_input, '',
'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxY yZz_. !'), ' ', '') =
'' then 0
ELSE CAST(REPLACE(TRANSLATE(p_input, '',
'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxY yZz_. !'),
' ', '') AS INTEGER)

If it can cast p_input as an INT, it returns it, otherwise it
returns a zero..

HTH

aj

kangaroo wrote:
Hello,

I have a column of type VARCHAR, storing some generally character data.
A few of the values in that column are in fact numbers represented as
strings (e.g., "12345").

At some moment I need to select those numbers, cast them to INT and do
some math on them. Naturally, I do something like this:

SELECT INT(MYCOLUMN) WHERE I_BELIEVE_THIS_IS_A_NUMBER='true'

However, due to glitches in the logic that writes into MYCOLUMN,
sometimes it gets populated with values that are not castable to INT
(for example, a string with a carriage return in it). In that case, I
get -420 in my stored proc, and the query aborts.

What is the best way of rewriting a query like this to make sure that
it does not abort during execution? I am okay with INT(MYCOLUMN)
returning NULL on a dirty value.

I see several options, in order of decreasing preference:

1. Find a native DB2 casting function that would be tolerant of bad
charaters (could not find one so far).

2. Write a UDF that'll essentially only take digits from an input
string, and then convert that to INT.

I am going to fix the logic that writes into MYCOLUMN, to do my best to
have only values castable to INT. However, I'd like to see if may be
there's a function for 1) above, or if someone sees a better solution.

Thanks
Bogdan Sheptunov

Dec 5 '05 #3
Serge, aj,

thank you.

Bogdan

Dec 5 '05 #4
kangaroo,

GETNUMBER returns integer even if input parameter(p_input) is mixed
digits and alphabet. Does it meet your requirement?

For example:
------------------------- Commands Entered -------------------------
VALUES GETNUMBER('1A2B3C4D5E');
--------------------------------------------------------------------

1
-----------
12345

1 record(s) selected.

Dec 6 '05 #5
Tonkuma,

no, it does not.

Here's a solution proposed by my coworker, who essentially joined
Serge's and aj's solutions:

CREATE FUNCTION GET_INT (vc_in VARCHAR (500))
RETURNS INTEGER
LANGUAGE SQL
CONTAINS SQL
DETERMINISTIC
NO EXTERNAL ACTION
RETURN CASE
WHEN vc_in = '' THEN NULL
WHEN TRANSLATE (vc_in, '', '1234567890') = '' THEN CAST (vc_in AS
INTEGER)
ELSE NULL
END
@

Bogdan

Dec 8 '05 #6
The only issue with that, which you may not worry about, is preceding
and trailing spaces. Trailing spaces would be an issue if the field is
CHAR. The INTEGER() FUNCTION itself allows preceding spaces.

So:

CREATE FUNCTION Get_Int(Text VARCHAR(4000))
RETURNS INTEGER
SPECIFIC Get_Int
DETERMINISTIC
NO EXTERNAL ACTION
CONTAINS SQL
RETURN
CASE
WHEN LTRIM(RTRIM(TRANSLATE(Text, '1', '1234567890'))) =
REPEAT('1', LENGTH(LTRIM(RTRIM(Text))))
THEN INTEGER(Text)
ELSE NULL
END

If you really don't want preceding or trailing spaces:

CREATE FUNCTION Get_Int(Text VARCHAR(4000))
RETURNS INTEGER
SPECIFIC Get_Int
DETERMINISTIC
NO EXTERNAL ACTION
CONTAINS SQL
RETURN
CASE
WHEN TRANSLATE(Text, '1', '1234567890') = REPEAT('1', LENGTH(Text))
THEN INTEGER(Text)
ELSE NULL
END
B.

Dec 12 '05 #7
Oops, forgot to repeat those 1s. Hmm.. and once at it, might as well
remove the 1 from the TRANSLATE.

CREATE FUNCTION Get_Int(Text VARCHAR(4000))
RETURNS INTEGER
SPECIFIC Get_Int
DETERMINISTIC
NO EXTERNAL ACTION
CONTAINS SQL
RETURN
CASE
WHEN LTRIM(RTRIM(TRANSLATE(Text, '111111111', '234567890'))) =
REPEAT('1', LENGTH(LTRIM(RTRIM(Text))))
THEN INTEGER(Text)
ELSE NULL
END
If you really don't want preceding or trailing spaces:
CREATE FUNCTION Get_Int(Text VARCHAR(4000))
RETURNS INTEGER
SPECIFIC Get_Int
DETERMINISTIC
NO EXTERNAL ACTION
CONTAINS SQL
RETURN
CASE
WHEN TRANSLATE(Text, '111111111', '234567890') = REPEAT('1',
LENGTH(Text))
THEN INTEGER(Text)
ELSE NULL
END

B.

Dec 12 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

31
by: Jamie Burns | last post by:
Hello, I am writing a client / server application. There is 1 server, and many clients. The server processes requests from each client, and typically creates and manipulates C++ objects on their...
2
by: grahamo | last post by:
Hi, i know I should use the new style casts and I intend to however I would like to know how I go about this; I have an unsigned char* that a 3rd party API returned to me. The API reads text...
3
by: John Howard | last post by:
Making the following call to a local MSAccess database works fine: Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs) Dim intRows As Integer Dim strSQL As String Dim ds As New...
1
by: Hifni Shahzard | last post by:
Hi, I got a stored procedure, where it returns a value. But if I execute it. It gives an error as "Invalid cast from System.Int32 to System.Byte.". To make clear how do I execute this, below I'm...
3
by: Mike Cooper | last post by:
Hello All! I am getting teh above error message on the following code: Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim dgt As...
3
by: BoloBaby | last post by:
All, I believe I am having a threading problem. Class "BELights" is part of a larger DLL that is used by my main application. A user control (of type BESeat) within the main application raises...
6
by: John-Arne Lillebø | last post by:
Hi. I run into this problem and i could need some help to solve it. The project is an ASP.NET Web project. Including code sample of the problem. Any idea what is causing the error message ?...
11
by: Dinsdale | last post by:
I am trying to determine what the current cast of an object is. Essentially, if I use GetType, it always returns the original type of the object created but I want to know what the current cast of...
18
by: digz | last post by:
Hi , I am trying to write a class that encapsulates a Union within it , I intend the code to be exception safe. can someone please review it and tell me if I have done the right thing , are...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.