Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

variable type

by Losing (Acolyte)
on Dec 07, 2006 at 14:40 UTC ( [id://588336]=perlquestion: print w/replies, xml ) Need Help??

Losing has asked for the wisdom of the Perl Monks concerning the following question:

Is it possible to determine an integer from a string? Like and int($x) function? I know this is normal in strongly typed languages like C, but obviously it is different with Perl's situational data typing. I'm inserting values into a database and DB2 simply will not accept '2' as an integer, I must insert it as 2. So I need a way to check if some variable is an integer. Here is some context:
$table = 'sometable'; $col1 = 'id'; $col2 = 'name; $val1 = 3; $val2 = 'somename'; &insert($table, $col1, $col2, $val1, $val2);
The insert function uses the values to build an SQL query string.

Replies are listed 'Best First'.
Re: variable type
by Corion (Patriarch) on Dec 07, 2006 at 14:52 UTC

    Show us the code of your sub insert {...}, because that is where the string or number distinction has to be made. Also consider how you will try to insert a string that looks_like_a_number, like "3".

    Is there any reason why you aren't using DBI placeholders instead?

      I didn't know of the existence of DBI placedholders. :( . Lolz. Thanks, just saved me a couple of weeks worth of coding. I'm new to databases :(.
Re: variable type
by Joost (Canon) on Dec 07, 2006 at 14:51 UTC
      That's almost correct. $ will match an optional newline as well, so both "5" and "5\n" are valid. Better to use \z

      print "1. number\n" if "5" =~ /^\d+$/; print "1. number and newline\n" if "5\n" =~ /^\d+$/; print "2. number\n" if "5" =~ /^\d+\z/; print "2. number and newline\n" if "5\n" =~ /^\d+\z/
      Update
      The advice to use a \z fixes the problem of bad data being submitted, but it might block otherwise good data, depending on the input source. Data read from a filehandle could have the newline present, without it being from a misbehaving user.
      chomping the field in question is a better approach than being stricter with the regex.
Re: variable type
by Fletch (Bishop) on Dec 07, 2006 at 14:52 UTC

    If you're using DBI and placeholders then it should figure out the numericalityness of values and send them to the database correctly. If it's not you can use the bind_param method on a statement handle to explicitly set the SQL type a given placeholder should have. See the DBI docs for more details.

Re: variable type
by jdporter (Paladin) on Dec 07, 2006 at 17:18 UTC

    You should also know about Scalar::Util's function, looks_like_number.

    We're building the house of the future together.
Re: variable type
by ikegami (Patriarch) on Dec 07, 2006 at 19:25 UTC

    That shouldn't be an issue if you're using placeholders. DBI knows if it's suppose to be an number or a string based on information it obtains from the database.

    sub escape_name { my $t = @_ ? $_[0] : $_; $t =~ s/`/``/g; return "`$t`"; } my $table = 'sometable'; my @cols = qw( id name ); my @vals = qw( 3 somename ); my $stmt = "INSERT INTO " . escape_name($table) . " (" . join(', ', map escape_name, @cols) . ") VALUES (" . join(', ', (?) x @cols) . ")"; my $sth = $dbh->prepare($stmt); $sth->execute(@vals);

    I'm using MySQL's escape mechanism for table names and column names. I don't know if DB2 uses the same mechanism.

      $dbh->quote_identifier is the portable version of escape_name

      my $table = 'sometable'; my @cols = qw( id name ); my @vals = qw( 3 somename ); my $stmt = "INSERT INTO " . $dbh->quote_identifier($table) . " (" . join(', ', map { $dbh->quote_identifier($_) } @cols) . ") VALUES (" . join(', ', (?) x @cols) . ")"; my $sth = $dbh->prepare($stmt); $sth->execute(@vals);
Re: variable type
by madbombX (Hermit) on Dec 07, 2006 at 16:10 UTC
    If you are unsure about weather something is an integer or not, you can always multiply it by 1 to force it into integer context. Be careful since this is dangerous as you are forcing data to change. For example:

    Now consider the following code (use lines removed for brevity):

    Lastly, consider this piece of code forcing the string or integer into integer context. Notice the exponentiation doesn't throw an error because the input was forced into integer context.

    my $x = <STDIN>; $x *= 1; print "String\n" if ($x =~ /\w/); print "Integer\n" if ($x =~ /\d/); print $x**$x ."\n"; __OUTPUT__ 2 String Integer 4

    Note: The reason its a string and an integer is in the case of \w (which is what the regex uses), it checks for [0-9a-zA-Z] as well.

Re: variable type
by themage (Friar) on Dec 07, 2006 at 14:49 UTC
    Hi Losing,

    You have the usual way to verify if a variable is numeric, and that would be to use a regexp:
    unless ($val1=~/\A[-+]?\d+\.?\d*\Z/) { #quote here $val1, for example: $val1=$dbh->quote($val1); }


    I'm obviously, assuming that $dbh->quote for a DB2 connection don't quote the values correctly, that I think should happen.

    TheMage
    Talking Web
Re: variable type
by Losing (Acolyte) on Dec 07, 2006 at 15:11 UTC
    So now I have a new problem. I am writing an insert_row function. I do not know how many columns I will be inserting, how would I dynamically handle the call to $sth->execute? The DBI documentation offers up this nice example, but how would I change it to handle a dynamic number of columns?
    my $sth = $dbh->prepare(q{ INSERT INTO sales (product_code, qty, price) VALUES (?, ?, ?) }) or die $dbh->errstr; while (<>) { chomp; my ($product_code, $qty, $price) = split /,/; $sth->execute($product_code, $qty, $price) or die $dbh->errstr; } $dbh->commit or die $dbh->errstr;

      DBI is OK has some sample code you might enjoy.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://588336]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (7)
As of 2024-04-23 14:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found