我的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文件之前清空两个表?
提前致谢!
答案 0 :(得分:2)
为什么要使用PHP呢?我会在SQL中本地完成这些:
定义表格(如果尚未完成)。请注意,您必须在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)
);
定义要导入原始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
);
定义AFTER INSERT
trigger,它将拆分导入的数据,并在“真实”表格中执行相关插入操作。您可以将INSERT ... ON DUPLICATE KEY UPDATE
与LAST_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 ;
导入数据:
LOAD DATA INFILE '/path/to/file.csv'
INTO TABLE import
FIELDS TERMINATED BY ','
;
整理:
DROP TRIGGER trig;
DROP TABLE import;
或者(取决于您是否打算将来重复使用它):
TRUNCATE import;