#! perl -slw use Benchmark::Timer; use strict; use constant SHORT_MIN => -32768; use constant SHORT_MAX => 32767; use constant LONG_MIN => -2147483648; use constant LONG_MAX => 2147483647; use constant FLOAT_MIN => 1.175 * 10 ** -38; use constant FLOAT_MAX => 3.402 * 10 ** 38; use constant DOUBLE_MIN => 1.175 * 10 ** -308; use constant DOUBLE_MAX => 3.402 * 10 ** 308; use constant RE_NUMERIC => qr/^ [+-]? (?: (\d+) (?:\.(\d*))? | (?:\.(\d+)) ) ([Ee][+-]?\d+)? $/x; my $t = new Benchmark::Timer; while( ) { $t->start('GMDT'); print GetMinimalDataType($_); $t->stop('GMDT'); }; $t->report; exit; sub GetMinimalDataType { my $varValue = $_[0]; my ($iScale, $iPrecision, $szIntegerPart, $szDecimalPart, $szFloatPart); return 'NULL' unless $varValue; return 'CHAR(' . length($varValue) . ')' unless $varValue =~ RE_NUMERIC; #Check for numeric types $szIntegerPart = ($1||''); $szDecimalPart = ($2||'') . ($3||''); $szFloatPart = ($4||''); #Is this a simple integer? if ($szIntegerPart ne '' and $szDecimalPart eq '' and $szFloatPart eq '' ) { #SMALLINT 16 bits ?32,768 to 32,767 Signed short (word) return 'SMALLINT' if $varValue >= SHORT_MIN and $varValue <= SHORT_MAX; #INTEGER 32 bits ?2,147,483,648 to 2,147,483,647 Signed long (longword) return 'INTEGER' if $varValue >= LONG_MIN and $varValue <= LONG_MAX; } #Is this a simple decimal? if ( not $szFloatPart) { $iScale = length $szDecimalPart; $iPrecision = (length $szIntegerPart) + $iScale; return "DECIMAL($iPrecision,$iScale)" if $iPrecision >= 1 and $iPrecision <= 18 #Precision = 1 to 18 and $iScale >= 0 and $iScale <= 18 #Scale = 0 to 18 and $iScale <= $iPrecision; #Scale must be <= to precision } #Float maybe? #1.175 x 10 ?38 to 3.402 x 10 38 return 'FLOAT' if $varValue >= FLOAT_MIN and $varValue <= FLOAT_MAX; #2.225 x 10 ?308 to 1.797 x 10 308 return 'DOUBLE PRECISION' if $varValue >= DOUBLE_MIN and $varValue <= DOUBLE_MAX; #Dates here eventually # #Check for strings return 'CHAR(' . length($varValue) . ')'; } __DATA__ 0e0 0 +0 -0 1. 0.14 .14 1.24e5 24e5 -24e-5 2.3. 2.3.4 1..2 .1.1 4. .23-2147483648 2147483647 +2147483647 -2147483649 2147483648 10e10 10e-10 Dom Dominic Dominic Bush .... For the 500 trials I simply replicated the original test data 20 times.