更新记录时,PDO会丢失小数精度

时间:2017-10-09 03:36:49

标签: php mysql pdo

我正在尝试使用HTML表单和PHP脚本更新数据库中的表,我正在使用带有预处理语句和命名占位符的pdo

这是执行前的sql:

UPDATE lctn_bt SET `BTlongitude` = :BTlongitude, `BTlatitude` = :BTlatitude, `BTaccuracy` = :BTaccuracy, `BTnotes` = :BTnotes, `ISShaft` = :ISShaft, `ClientID` = :ClientID WHERE BTid = 79

这是我要输入执行语句的数组:

Array ( [:BTlongitude] => 144.9687500 [:BTlatitude] => -37.7452700 [:BTaccuracy] => 4 [:BTnotes] => Audit. To right of driveway [:ISShaft] => [:ClientID] => 0 )

以下是构建规则并执行它的代码:

$sql4 = "UPDATE ".$table." SET ";

    foreach($values3 as $key => $string){
        if($fields[$key] !== $primaryID){
            $sql4 = $sql4."`".$fields[$key]."` = :".$fields[$key].", ";
            $prepared[':'.$fields[$key]] = $string;
            echo $fields[$key].': '.$string.'</br>';
        }
    }
    $sql4 = substr($sql4, 0, -2);
    $sql4 = $sql4." WHERE ".$primaryID." = ".$record;
    echo $sql4;
    $sql4 = $dbh->prepare($sql4);
    $out = $sql4->execute($prepared);

如果我要使用数组顶部执行该语句,则在“BTlatitude”和“BTlongitude”的值中舍入到144.0000000和-37.0000000,即使数据库中的2个字段设置为“decimal”(12 ,7)“和同一表中的其他记录存储完整的值。事实上,我试图存储的值最初从该表中读取。

然而,如果我接受SQL语句并手动输入值,然后使用phpMyAdmin运行SQL,它可以正常工作并存储小数位。

这是我的头脑,我在同一个问题上找到的唯一其他在线帖子源于人们试图在没有定义小数位的十进制字段中存储小数位(例如。十进制(10,0))

上面的数组是print_r($ prepared);放在最后一行之后($ out = $ sql4-&gt;执行($ prepared);)并显示正确的值。

如果我运行以下代码,则会成功添加记录,所有小数位都保持不变:

$prepared = array(':BTlongitude' => 144.9687500, ':BTlatitude' => -37.7452700, ':BTaccuracy' => 4, ':BTnotes' => "Audit. To right of driveway", ':ISShaft' => '',':ClientID' => 0, ':BTid' => 79);

$dbh = new PDO("mysql:host=$db->host;dbname=$db->db_name", $db->username, $db->password);

$sql = "UPDATE lctn_bt SET `BTlongitude` = :BTlongitude, `BTlatitude` = :BTlatitude, `BTaccuracy` = :BTaccuracy, `BTnotes` = :BTnotes, `ISShaft` = :ISShaft, `ClientID` = :ClientID WHERE BTid = :BTid";
$sql = $dbh->prepare($sql);
$out = $sql->execute($prepared);

表格设置如下:

CREATE TABLE `lctn_bt` (
 `BTid` int(11) NOT NULL,
 `BTproperty` int(11) DEFAULT NULL,
 `BTlongitude` decimal(12,7) DEFAULT NULL,
 `BTlatitude` decimal(12,7) DEFAULT NULL,
 `BTaccuracy` int(11) DEFAULT NULL,
 `BTnotes` varchar(1000) DEFAULT NULL,
 `ISShaft` int(11) DEFAULT NULL,
 `ClientID` int(11) DEFAULT '0',
 `LastUpdated` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

1 个答案:

答案 0 :(得分:0)

原来这是铸造的问题。我正在使用:

$somevalue = htmlentities($_POST'somevalue'], ENT_HTML5, 'UTF-8');

在代码中,我认为它将小数位转换为等效的html实体。

我换了

$somevalue = htmlspecialchars($_POST'somevalue'], ENT_HTML5, 'UTF-8');

然后在我为pdo构建值数组的地方我检查了数字并强制使用以下代码将类型转换为浮点数:

if(is_numeric($string)){
    $prepared[':'.$fields[$key]] = floatval($string);
} else {
    $prepared[':'.$fields[$key]] = $string;
}

这似乎已经成功了。