使用PHP PDO将CSV逐行插入Postgres
我试图让用户上传一个文件,然后让该文件被插入到一个postgres数据库的行 我有此代码,我的语法出现以下错误: 数组([0]=>42601[1]=>7[2]=>错误:在或附近出现语法错误 “插入”“第1行:”插入“公共”。“tblSedimentGrabEvent” 值('A1000'…^) 我一直在看PHP PDO手册和Postgres网站,也在搜索错误代码,但仍然没有成功。我知道它可能很小,但它让我感到困惑使用PHP PDO将CSV逐行插入Postgres,php,postgresql,csv,pdo,insert-into,Php,Postgresql,Csv,Pdo,Insert Into,我试图让用户上传一个文件,然后让该文件被插入到一个postgres数据库的行 我有此代码,我的语法出现以下错误: 数组([0]=>42601[1]=>7[2]=>错误:在或附近出现语法错误 “插入”“第1行:”插入“公共”。“tblSedimentGrabEvent” 值('A1000'…^) 我一直在看PHP PDO手册和Postgres网站,也在搜索错误代码,但仍然没有成功。我知道它可能很小,但它让我感到困惑 <?php try { $db = new PDO("pgsql:
<?php
try {
$db = new PDO("pgsql:dbname=name;host=host","user","pass");
}
catch(PDOException $e) {
echo $e->getMessage();
}
if ($_FILES["file"]["error"] > 0)
{
echo "Error: " . $_FILES["file"]["error"] . "<br>";
}
else
{
echo "Uploaded Successfully!<br>";
echo "File Name: " . $_FILES["file"]["name"] . "<br>";
echo "Type: " . $_FILES["file"]["type"] . "<br>";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "Temp file: " . $_FILES["file"]["tmp_name"]. "<br>";
{
move_uploaded_file($_FILES["file"]["tmp_name"],
"D:/Apapub/public_html/databases/B13/temp/" . $_FILES["file"]["name"]);
echo "Stored in: " . "D:\Apapub\public_html\databases\B13\temp" . $_FILES["file"]["name"]. "<br>";
}
}
$file_handle = fopen("D:/Apapub/public_html/databases/B13/temp/grabevents.txt", "r");
while (!feof($file_handle) ) {
$text_file = fgetcsv($file_handle);
print_r($text_file);
$query=<<<eof
"INSERT INTO "public"."tblSedimentGrabEvent" VALUES ('$text_file[0]','$text_file[1]','$text_file[2]','$text_file[3]','$text_file[4]','$text_file[5]','$text_file[6]','$text_file[7]','$text_file[8]','$text_file[9]','$text_file[10]','$text_file[11]','$text_file[12]','$text_file[13]','$text_file[14]','$text_file[15]','$text_file[16]','$text_file[17]','$text_file[18]','$text_file[19]','$text_file[20]','$text_file[21]','$text_file[22]','$text_file[23]')"
eof;
$sth = $db->query($query);
}
if (!$sth) {
echo "<p>\nPDO::errorInfo():\n</p>";
print_r($db->errorInfo());
}
fclose($file_handle);
echo "<p><b>Records Imported</b></p>";
?>
我成功地使用了COPY命令,但我的主管希望它逐行解析,以便稍后运行一些检查
!!回答!!
我不知道如何给@Spudley道具,但他帮我回答了这个问题
在做了他所说的之后,我发现我不需要在查询中加引号(我想这是因为我使用了herdoc?)
这是有效的(但是:由Craig Ringer编辑,这仍然是危险的不安全的,永远不应该使用,不要将此作为示例代码复制):
$query=将文本替换到SQL中容易出错、不安全、难以调试且风格糟糕。请使用参数化语句,无论是PDO还是pg_query_params
。您的“答案”完全不安全,请不要使用它
这不仅可以解决您的问题,还可以保护您免受一系列严重安全漏洞的侵害,包括SQL注入。请参阅,以及
我也看到了
当你在使用时,考虑使用<代码>拷贝>代码>,这是非常有效的,只是将CSV直接流到PostgreSQL中的一个表中。参见或下级<代码> PGLPtuthLoe< /Cuff>函数。
< P>我从本页得到了答案:
我的代码是这样结束的:
$file_handle = fopen("D:/Apapub/public_html/databases/B13/temp/grabevents.txt", "r");
while (!feof($file_handle) ) {
$text_file = fgetcsv($file_handle);
foreach($text_file as &$val)
$val=$db->quote($val);
$data = implode(',',$text_file);
$q = $db->prepare('Insert Into "public"."tblSedimentGrabEvent" Values ('.$data.')');
$q->execute();
}
现在,它可以很好地工作,同时有望防止SQL注入。尝试echo
取消查询,而不是运行查询;如果可以看到实际的查询字符串,您可能可以更清楚地看到查询中的错误。如果没有帮助,请尝试将其粘贴到您最喜欢的DB GUI中进行进一步分析。谢谢@Spudley that帮助我看到了错误。我回显了查询,然后将其复制到PGAdminIII并运行它。结果表明,当我使用heredoc时,我不需要在查询周围加任何引号。这起作用:$query=我不明白为什么你不使用COPY
。它经过了尝试、测试、简单,并且有效。这是我最初使用的,但这方面的领先project希望逐行输入数据,以便我可以检查输入的数据。例如,在“已提交”列中,如果输入等于“是”,则该行将不会输入数据库。确定,因此您希望筛选输入。这是合理的。有时我希望这样做时所做的是将整个输入复制到stagin中gTEMPORARY
table然后使用SQL将其与最终的表合并。这通常更快、更简单,但我想这取决于您是否更擅长PHP或SQL。我对这两种方法都不是很在行,临时表的想法听起来是一个很好的方法。这是我的第一个“大”问题“项目编程所以这是一种学习体验。感谢您的帮助。如果允许COPY
,那么它通常是优越的,但在某些情况下是不允许的。这种设置在web服务器上很常见,因为exec()
PHP中的调用通常是不允许的,即使是这样,也可能不允许对psql接口进行身份验证。从安全角度来看,允许在web服务器上执行这些操作通常不是最佳做法。因此,可能需要使用STDIN的逐行方法。
$query=<<<eof
INSERT INTO "public"."tblSedimentGrabEvent" VALUES ('$text_file[0]','$text_file[1]','$text_file[2]','$text_file[3]','$text_file[4]','$text_file[5]','$text_file[6]','$text_file[7]','$text_file[8]','$text_file[9]','$text_file[10]','$text_file[11]','$text_file[12]','$text_file[13]','$text_file[14]','$text_file[15]','$text_file[16]','$text_file[17]','$text_file[18]','$text_file[19]','$text_file[20]','$text_file[21]','$text_file[22]','$text_file[23]')
eof;
$sth = $db->query($query);
$file_handle = fopen("D:/Apapub/public_html/databases/B13/temp/grabevents.txt", "r");
while (!feof($file_handle) ) {
$text_file = fgetcsv($file_handle);
foreach($text_file as &$val)
$val=$db->quote($val);
$data = implode(',',$text_file);
$q = $db->prepare('Insert Into "public"."tblSedimentGrabEvent" Values ('.$data.')');
$q->execute();
}