使用php在不同的sql表中导入选定的csv文件列

时间:2014-04-20 10:33:35

标签: php mysql sql csv

我的csv文件如下所示:

Name | DateOfBirth| Gender| Occupation| DateOfTest | FieldNumber | Eye | ThresholdValue

Fred, 12/08/68,M, carpenter, 12/02/06, 1, R, 1234
Susan, 3/09/72, F, hairstylist, 12/04/07, 1, R, 1234
Fred, 12/08/68,M, carpenter, 12/02/06, 1, L, 1234
Susan, 3/09/72, F, hairstylist, 12/04/07, 1, L, 1234
Fred, 12/08/68,M, carpenter, 12/02/08, 1, R, 1234
Susan, 3/09/72, F, hairstylist, 12/04/08, 1, R, 1234
Fred, 12/08/68,M, carpenter, 12/02/08, 1, L, 1234
Susan, 3/09/72, F, hairstylist, 12/04/08, 1, L, 1234
每个患者对于他们进行的每个测试实例都有两排(左眼和右眼),他们可以进行多次测试。我必须将这些信息放在数据库中,以便从不同的维度中提取,例如分析来自所有女性的数据,或者分析来自所有木匠的数据等。我想到了以下两个表:

Patient_info
PatientID(auto-increment primary key), name, dob, gender, occupation 

test_info
testID(auto-increment primary key), patientID(foreign key from patient_info), dot, fieldnumber, eye, thresholdvalue 

我已经能够使用php的fgetcsv()函数填充patient_info表。 $ sql工作正常,但$ sql2没有。

<?php



    ini_set("auto_detect_line_endings", true);
    include "connection.php";

    $deleterecords = "TRUNCATE TABLE patient_info";
    mysql_query($deleterecords);

    $deleterecords = "TRUNCATE TABLE test_info";
    mysql_query($deleterecords);    

    if(isset($_POST['submit']))
    {

        $file = $_FILES['file']['tmp_name'];

        $handle = fopen($file,"r");

        while(($fileop = fgetcsv($handle, 1000, ",")) !== false)
        {
            $name = $fileop[0];
            $dateofbirth = $fileop[1];
            $gender = $fileop[2];
            $occupation = $fileop[3];
            $dateoftest = $fileop[4];
            $field = $fileop[5];
            $eye = $fileop[6];
            $thresholdvalues = $fileop[7];
            $sql = mysql_query("INSERT INTO patient_info (Name, DateOfBirth, Gender, Occupation) VALUES ('$name','$dateofbirth','$gender','$occupation')" );
            $sql2 = mysql_query("INSERT INTO test_info (DateOfTest, FieldNumber, Eye, ThresholdValues) VALUES   ('$dateoftest','$field','$eye','$thresholdvalues')" );

        }
            fclose($handle);
            if($sql2) { echo 'test data successfully uploaded';}

            if($sql) 
            {
                echo 'Data uploaded successfully';
                header("Location: http://localhost/lei/test.com/proper/upload_page.php");
                exit();
            }
            else
            {
                echo 'Upload Failed';
            }

    }

?>

问题: 1)如何在patient_info表中为每个患者只插入一条记录,但是在test_info表中为患者进行的每个测试实例都有多条记录? 2)我应该如何使用patient_info表中的patientID和csv文件中的其他值填充test_info表? 3)我想在每次上传新的csv文件时清空两个表。我使用TRUNCATE查询来做到这一点,但由于我将PatientID定义为外键,因此TRUNCATE不起作用。如何在上传新的csv文件之前清空两个表?

提前致谢!

1 个答案:

答案 0 :(得分:2)

为什么要使用PHP呢?我会在SQL中本地完成这些:

  1. 定义表格(如果尚未完成)。请注意,您必须在patient_info中的相关列上定义唯一性约束,通过该列可以从CSV数据中识别匹配的患者:

    CREATE TABLE patient_info (
      PatientID      SERIAL,
      Name           VARCHAR(255),
      DateOfBirth    DATE,
      Gender         ENUM('M','F'),
      Occupation     VARCHAR(255),
      UNIQUE(Name, DateOfBirth, Gender, Occupation)
    );
    
    CREATE TABLE test_info (
      TestID         SERIAL,
      PatientID      BIGINT UNSIGNED,
      DateOfTest     DATE,
      FieldNumber    INT UNSIGNED,
      Eye            ENUM('R','L'),
      ThresholdValue INT UNSIGNED,
      FOREIGN KEY (PatientID) REFERENCES patient_info (PatientID)
    );
    
  2. 定义要导入原始CSV数据的表格:

    CREATE TABLE import (
      Name           VARCHAR(255),
      DateOfBirth    DATE,
      Gender         ENUM('M','F'),
      Occupation     VARCHAR(255),
      DateOfTest     DATE,
      FieldNumber    INT UNSIGNED,
      Eye            ENUM('R','L'),
      ThresholdValue INT UNSIGNED
    );
    
  3. 定义AFTER INSERT trigger,它将拆分导入的数据,并在“真实”表格中执行相关插入操作。您可以将INSERT ... ON DUPLICATE KEY UPDATELAST_INSERT_ID()一起使用来获取每条记录的PatientID,即使它已经存在:

    DELIMITER //
    CREATE TRIGGER trig AFTER INSERT ON import FOR EACH ROW BEGIN
      INSERT INTO patient_info (
        Name,
        DateOfBirth,
        Gender,
        Occupation
      ) VALUES (
        NEW.Name,
        NEW.DateOfBirth,
        NEW.Gender,
        NEW.Occupation
      ) ON DUPLICATE KEY UPDATE
        PatientID = LAST_INSERT_ID(PatientID)
      ;
    
      INSERT INTO test_info (
        PatientID,
        DateOfTest,
        FieldNumber,
        Eye,
        ThresholdValue
      ) VALUES (
        LAST_INSERT_ID(),
        NEW.DateOfTest,
        NEW.FieldNumber,
        NEW.Eye,
        NEW.ThresholdValue
      );
    END//
    DELIMITER ;
    
  4. 导入数据:

    LOAD DATA INFILE '/path/to/file.csv'
      INTO TABLE import
      FIELDS TERMINATED BY ','
    ;
    
  5. 整理:

    DROP TRIGGER trig;
    DROP TABLE import;
    

    或者(取决于您是否打算将来重复使用它):

    TRUNCATE import;