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?
| [reply] [d/l] [select] |
|
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 :(.
| [reply] |
Re: variable type
by Joost (Canon) on Dec 07, 2006 at 14:51 UTC
|
You don't want to know if a value is a string or number, since you're building SQL so they're always converted to strings. You want to know if the string only contains numbers digits. You should probably use DBI's $dbh->quote or placeholders. But otherwise my $is_num = $value =~ /^-?\d+(\.\d+)?$/;
| [reply] [d/l] [select] |
|
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. | [reply] [d/l] |
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.
| [reply] [d/l] |
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.
| [reply] |
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.
| [reply] [d/l] |
|
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);
| [reply] [d/l] [select] |
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. | [reply] [d/l] [select] |
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.
| [reply] [d/l] |
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;
| [reply] [d/l] |
|
| [reply] |