0

csv ファイルから電子メール アドレスをアップロードするスクリプトを作成しようとしていますが、挿入する前に、そのアドレスが 2 つの異なるテーブルに既に存在するかどうかも確認します。私は完璧に機能するこのクエリを持っています:

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 は機能しません。1 つのインバウンド レコードだけでなく、「各」インバウンド レコードを比較する必要があります。したがって、list_email.email_addr 列にバインドされた $email_addr である必要があります (まだ存在しない場合) $_FILES['userfile'] キーにアクセスして、$email_addr などのデータにアクセスして比較。$_FILES の var_dump() は、'userfile' をキーとして test.csv を表示しますが、中に入ることはできません。$_POST には私のrow_nameがあり、正常に動作します。

  <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>

** * ** * ** * ** * ** * var_dump() * ** * ** * ** * ** * ** * ****

    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
4

1 に答える 1

0

だから私はあなたのコードを少しきれいにしました。$_FILES[0]あなたが言及したエラーは、あなたが呼び出すという事実によって引き起こされ$_FILES[1]ます$_FILES[2]. ここには値がないため、null です。

さらに、コードにはまったく必要のないものがたくさんあります。

また、準備されたステートメントと、そこに変数を入力する方法を見てください!

説明させてください:

<?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 = "your desired value";
$lname = "your desired value";
$post_addr = "your desired value";

ここで明らかに値が必要です。これらは、読んだ行から取得されます。したがって、例では、これは次のようになります。

$fname = $data[0];
$lname = $data[1];
$post_addr = $data[2];

これらすべてに加えて、SQL クエリも失敗します。list_email要求している4 つの列にデータを挿入する必要がありますが、 3 つの変数のみを渡します。

また、2回渡した変数を選択する理由もわかりませんdual

編集

私が述べたように、あなたの SQL クエリは間違っています。

これを少し更新しました。 list_name の由来は?

更新されたクエリにMISSING_VALUEを追加しました。

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))
于 2013-09-03T08:56:33.023 に答える