PhP将CSV上载到MySQL,但不存在复杂的决斗
我试图创建一个脚本,从csv文件上传电子邮件地址,但在插入之前还要检查该地址是否已经存在于两个不同的表中。 我有一个完美的查询:PhP将CSV上载到MySQL,但不存在复杂的决斗,php,mysql,sql,csv,Php,Mysql,Sql,Csv,我试图创建一个脚本,从csv文件上传电子邮件地址,但在插入之前还要检查该地址是否已经存在于两个不同的表中。 我有一个完美的查询: INSERT INTO list_email (fname, lname, email_addr) SELECT ins.* FROM ( SELECT 'bob' AS fname, 'schmoe' AS lname, 'bogus@bogus.com' AS email_addr FROM dual UNION ALL SELECT 'mary', 'lamb'
INSERT INTO list_email (fname, lname, email_addr)
SELECT ins.* FROM ( SELECT 'bob' AS fname,
'schmoe' AS lname,
'bogus@bogus.com' AS email_addr
FROM dual UNION ALL
SELECT 'mary', 'lamb', 'hoe@me.com'
FROM dual ) AS ins WHERE NOT EXISTS
( SELECT 1
FROM list_email AS e
WHERE e.email_addr = ins.email_addr
) AND NOT EXISTS
( SELECT 1
FROM list_no_email AS ne
WHERE ne.email_addr = ins.email_addr );
但由于这是一个文件上传脚本,原因显而易见bogus@bogus.com就是不管用。我需要比较“每个”入站记录,而不仅仅是一条。因此,list\u email.email\u addr列必须绑定$email\u addr(如果它不存在)
我似乎无法访问$_FILES['userfile']键来访问数据,比如$email\u addr来进行比较。$u文件的var_dump()是否显示test.csv,并将“userfile”作为键,但我无法进入其中$_这篇文章有我的行名,效果很好
<form enctype="multipart/form-data" method="POST">
<p> Give a unique name for your campaign </p>
<input name="row_name" type="text">
<br/>
<input name="userfile" type="file">
<br/>
<input type="submit" value="Upload">
</form>
<?php
$dsn = "mysql:host=$host;port=$port;dbname=$dbname"; //Data Source Name = Mysql
$db = new PDO($dsn, $db_username, $db_password); //Connect to DB
//var_dump($_FILES);
//var_dump($_POST);
if (isset($_POST['userfile']) && isset($_POST['row_name'])){
$insert = array(NULL, $data[0]." ".$data[1], $data[0],$data[1],$data[2]);
var_dump($insert);
$do = $db->prepare(
"INSERT INTO list_email(list_name, fname, lname, email_addr)
SELECT ins.*
FROM(
SELECT $data[1] AS fname,
$lname AS lname,
$data[3] AS email_addr
FROM dual
UNION ALL
SELECT $data[1], $data[2], $data[3]
FROM dual
) AS ins
WHERE NOT EXISTS(
SELECT 1
FROM list_email AS e
WHERE e.email_addr = ins.email_addr
)
AND NOT EXISTS(
SELECT 1
FROM list_no_email AS ne
WHERE ne.email_addr = ins.email_addr
)"
);
$csv_file = $_FILES['userfile']['tmp_name'];
// exit if file fail
if ( ! is_file( $csv_file ) )
exit('File not found.');
if (($handle = fopen($csv_file, "r")) !== FALSE) {
while (($data = fgetcsv($handle)) !== FALSE) {
//var_dump($insert);
$do->execute($insert);
}
fclose($handle);
}
}
exit( "Complete!" );
?>
</body>
</html>
**************表格********************
Notice: Undefined offset: 0 in /home/wemail1/www/pages/campaign-build.inc.php on line 35
Notice: Undefined offset: 1 in /home/wemail1/www/pages/campaign-build.inc.php on line 35
NULL array(1) { ["userfile"]=> array(5) { ["name"]=> string(9) "test1.csv"
+["type"]=> string(24) "application/vnd.ms-excel" ["tmp_name"]=> string(14)
+"/tmp/php5k0ppx" ["error"]=> int(0) ["size"]=> int(76) } }
> no values ^^
> var_dump($_FILES);
mysql> desc list_email;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| list_name | varchar(55) | YES | | NULL | |
| fname | char(50) | YES | | NULL | |
| lname | char(50) | YES | | NULL | |
| email_addr | varchar(150) | YES | | NULL | |
+------------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
mysql> desc list_no_email;
+------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| date_in | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| email_addr | varchar(150) | YES | | NULL | |
+------------+--------------+------+-----+-------------------+-----------------------------+
3 rows in set (0.00 sec)
http://stackoverflow.com/questions/18584541/mysql-insert-into-with-dual-condition-for-if-not-exist
所以我稍微整理了一下你的代码。尺寸标注错误是由调用
$\u文件[0]
、$\u文件[1]
和$\u文件[2]
引起的。这里没有值,因此为空
此外,您的代码有一堆根本不需要的东西
另外:看看准备好的语句以及如何在那里填充变量
让我解释一下:
<?php
$dsn = "mysql:host=$host;port=$port;dbname=$dbname"; //Data Source Name = Mysql
$db = new PDO($dsn, $db_username, $db_password); //Connect to DB
if (isset($_POST['userfile']) && isset($_POST('row_name']))){
//$rowname = $_POST['row_name']; (do you need this? You never call this anywhere below)
//Dont know why this is here
//$fname = $_FILES[0];
//$lname = $_FILES[1];
//$post_addr = $_FILES[2];
//PDO does not work with $var, instead use :var and fill the var before executing the query
$do = $db->prepare(
"INSERT INTO list_email(list_name, fname, lname, email_addr)
SELECT ins.*
FROM(
SELECT :fname AS fname,
:lname AS lname,
:post_addr AS email_addr
FROM dual
UNION ALL
SELECT :fname, :lname, :post_addr
FROM dual
) AS ins
WHERE NOT EXISTS(
SELECT 1
FROM list_email AS e
WHERE e.email_addr = ins.email_addr
)
AND NOT EXISTS(
SELECT 1
FROM list_no_email AS ne
WHERE ne.email_addr = ins.email_addr
)"
);
$do->bindParam(':fname', $fname);
$do->bindParam(':lname', $lname);
$do->bindParam(':post_addr', $post_addr);
$csv_file = $_FILES['userfile']['tmp_name'];
// exit if file fail
if ( ! is_file( $csv_file ) )
exit('File not found.'); //exit = bad practise, use proper error handling
if (($handle = fopen($csv_file, "r")) !== FALSE) {
while (($data = fgetcsv($handle)) !== FALSE)
{
//$insert = array(NULL, $data[0]." ".$data[1], $data[0],$data[1],$data[2]); (what is this? what does it do?)
//Fill the variables needed for the query
$fname = "your desired value";
$lname = "your desired value";
$post_addr = "your desired value";
//Execute the query
$do->execute();
}
fclose($handle);
}
}
else {
print "Something went wrong while trying IsSet";
}
?>
这里需要你的值,显然,这些值来自你读到的那行。
因此,在示例中,这将是:
$fname = $data[0];
$lname = $data[1];
$post_addr = $data[2];
除此之外,SQL查询也会失败。
您希望将数据插入您的列表\u电子邮件中,请求4列,但只传递3变量
我也不明白为什么要从dual
编辑
正如我所说的,您的SQL查询是错误的
我已经更新了一点。
列表名称来自哪里?
我现在在更新的查询中添加了缺少的\u值:
INSERT INTO list_email(list_name, fname, lname, email_addr)
SELECT ins.*
FROM(
SELECT ins.*
FROM
(
SELECT
'MISSING VALUE' as MISSING_VALUE
:fname AS fname,
:lname AS lname,
:post_addr AS email_addr
FROM dual
) as ins
WHERE
NOT EXISTS(
SELECT 1
FROM list_email AS e
WHERE e.email_addr = ins.email_addr)
AND
NOT EXISTS(
SELECT 1
FROM list_no_email AS ne
WHERE ne.email_addr = ins.email_addr))
$fname=$\u文件[0]$lname=$\u文件[1]$post_addr=$_文件[2]
提交文件[0]
的确切位置是哪里?(1和2相同)@Tikkes我从另一个开始就验证了它,我得到了同样的错误。if(是_数组($_文件['userfile'])){,我还尝试将其作为附加参数传递,但也失败了。$\u文件
没有键0
、1
或2
。它使用tmp\u名称
,…我只是查看了您在代码中所做的编辑,不知道您是否阅读了我的答案。$data
在准备好的语句中不起作用。Che再次勾选我的答案并仔细阅读,因为您所做的仍然是错误的。@Tikkes我如何访问tmp_name中的值?按键?非常感谢,尽管在进行了您建议的更改后,我没有收到任何错误,但没有数据进入数据库。我更新了上面的代码以反映更改。这是因为您的SQL查询是错误的仍然错误。您希望插入4个值,但从您的选择中只得到3个值。我已更新了代码,下面可以找到SQL查询,请查看缺少的值。如果这有帮助,请接受我的回答。此查询是有效的,并且执行它应该执行的操作,并测试了'but'而不是静态数据,我需要变量来适应上载的file。您所指的“缺失”是我试图从发布的文件或$\u文件[]中检索的内容,该值包含什么?文件名?其他内容?您的查询一开始需要4列,但只返回3个变量。这(来自粘贴)您知道,这似乎是固定的。此外,您在“从双选择”上执行了一个根本不必要的联合操作。什么仍然不起作用?您希望从$\u文件中得到什么来放入您的数据库?
INSERT INTO list_email(list_name, fname, lname, email_addr)
SELECT ins.*
FROM(
SELECT ins.*
FROM
(
SELECT
'MISSING VALUE' as MISSING_VALUE
:fname AS fname,
:lname AS lname,
:post_addr AS email_addr
FROM dual
) as ins
WHERE
NOT EXISTS(
SELECT 1
FROM list_email AS e
WHERE e.email_addr = ins.email_addr)
AND
NOT EXISTS(
SELECT 1
FROM list_no_email AS ne
WHERE ne.email_addr = ins.email_addr))