运行的环境如下。它是拇指驱动器上的Server2Go实例。
Apache/2.2.15 (Win32),
PHP/5.3.2,
SQLite 2,
MySQL 5.1.46-community,
and Perl 5.8.
php脚本打开一个文件并逐行循环。使用文件的每一行中的信息构建和执行查询。
表结构如下:
CREATE TABLE `exp_report` (
`b_unit` varchar(11) DEFAULT NULL, //IMPORTANT TO THIS PROBLEM
`b_unit_title` varchar(255) DEFAULT NULL,
`act_code` varchar(11) DEFAULT NULL,
`act_title` varchar(255) DEFAULT NULL,
`adopted_bgt` varchar(20) DEFAULT NULL,
`amended_bgt` varchar(20) DEFAULT NULL,
`encumb` varchar(20) DEFAULT NULL,
`ytd_exp` float(14,2) DEFAULT NULL, //IMPORTANT TO THIS PROBLEM
`encumb_ytdexp` float(14,2) DEFAULT NULL, //IMPORTANT TO THIS PROBLEM
`available_bgt` varchar(20) DEFAULT NULL,
`percent` varchar(20) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
执行脚本时,我回显在php脚本中执行查询之前和之后生成的查询语句。这是为了确保PHP中的数据不会发生任何奇怪的现象。
示例输出:
INSERT INTO exp_report (b_unit, b_unit_title, act_code, act_title, adopted_bgt,
amended_bgt, encumb, ytd_exp, encumb_ytdexp, available_bgt,
percent
)
VALUES('01000101', 'COUNCIL', '414000', 'SALARIES & WAGES', '259500','214500',
'0', '2', '209296.72', '5203.28', '0.97574228'
);
数据库中的结果如下所示:
010001 | COUNCIL | 414000 | SALARIES & WAGES | 259500 | 214500 | 0 | 2.00 | 2.00 | 5203.28 | 0.97574228
请注意上述数据的第一个字段和最后4个字段。
第一个字段是b_unit
varchar(11)`,程序尝试插入01000101但最后两位数字在存储在数据库中时被截断。
接下来的两个字段是ytd_exp
float(14,2)和encumb_ytdexp
float(14,2)。我试图插入' 209296.72'在encumb_ytdexp中,它被转换为2.00。
其余两个字段是varchars,它们正确存储信息。
如果我将回显到浏览器的查询复制并在phpMyAdmin中运行,则数据会正确存储,并且看起来与查询语句中传递的内容完全相同。
我似乎无法弄清楚造成这种行为的原因。
感谢任何建议。
php脚本的代码:
<?php
include('includes\db_fns.php');
$filename = "d2013expRep.xls";
$lines = file($filename);
foreach($lines as $key=>$current){
$contents = explode("\t",$current);
if($key=="0"){
continue;
}
$actr = 0;
//var_dump($contents);
foreach($contents as $key2=>$c2){
$la = trim($c2);
if($actr==0){
$finout .= "'".$la."'";
}else{
if($key2=="7"){
$la = (float) $la;
$finout .= ",'".$la."'";
}else{
$finout .= ",'".$la."'";
}
}
$actr++;
unset($la);
}
$query = "INSERT INTO exp_report (b_unit,b_unit_title,act_code,act_title,adopted_bgt,amended_bgt,encumb,ytd_exp,encumb_ytdexp,available_bgt,percent) VALUES($finout); ";
//echo($query."<BR><BR><BR>");
$result = mysqli_query($dc2a,$query) or trigger_error("Failed Query: " . mysqli_error($dc2a));
$finout .= "\r\n";
echo $query."<BR><BR><BR>";
unset($finout);
unset($actr);
}
//$query = "LOAD DATA LOCAL INFILE '/Library/WebServer/Documents/".$filename."' INTO TABLE exp_report FIELDS TERMINATED BY '\s\t' LINES TERMINATED BY '\n' IGNORE 1 LINES ";
//$result = mysqli_query($dc2a,$query) or trigger_error("Failed Query: " . mysqli_error($dc2a));
//echo $query;
?>
我尝试过所有受访者的建议无济于事。也许这些镜头将有助于阐明这个问题。
执行脚本后,数据将插入到数据库中。我使用文本/字符串而不是数字/小数/浮点数。现在,数据库告诉我,当我知道记录不存在时,记录不存在。
当我使用like执行查询时,结果为空集。我正在搜索的字段设置为文本字段。
这对任何人都有意义,还是我在追逐幽灵?
答案 0 :(得分:0)
很难看出你发布的内容有什么问题
确保读取文件是一个正确的制表符分隔文本文件:也许我错了,但是从扩展名.xls
开始,您似乎正在尝试读取本机Excel二进制文件(当我从Excel中保存为以制表符分隔的值时,我将.txt
作为扩展名,但我在Mac上...)
我重写了你的代码以便更清楚
另外(可能会解决问题)我添加了3件事:
在插入 values 字符串之前,每个值都转义。如果值包含单引号,这将保存您,例如
我在反引号之间附加了字段'名称,以避免潜在的mysql保留关键字冲突。
修改强>
希望这有帮助
<?php
include('includes\db_fns.php');
$filename = "d2013expRep.xls"; // <--- make sure you're importing properly tab separated text data (are you importing an xls file??)
$lines = file($filename);
foreach($lines as $lineNum => $line) {
// It seem you're working with a UTF-16 text file: convert to UTF8
$lineUTF8 = mb_convert_encoding( $line, "UTF-8", "UTF-16LE" );
$contents = explode( "\t", $lineUTF8 );
if($lineNum==0) {
continue;
}
$queryValues = "";
foreach( $contents as $valueNum => $value ) {
// good practice to escape the string
$queryValues .= ( $valueNum == 0 ? "" : ", " ) . "'" . mysql_escape_string( trim( $value ) ) . "'";
}
// backtick field names to avoid reserved keywords conflicts
$query = "INSERT INTO `exp_report` ( `b_unit`,
`b_unit_title`,
`act_code`,
`act_title`,
`adopted_bgt`,
`amended_bgt`,
`encumb`,
`ytd_exp`,
`encumb_ytdexp`,
`available_bgt`,
`percent` ) VALUES( $queryValues ); ";
$result = mysqli_query($dc2a,$query) or trigger_error("Failed Query: " . mysqli_error($dc2a));
// echo $query . "<br /><br />";
}
?>