Php 通过多个外键插入多个表

Php 通过多个外键插入多个表,php,mysql,foreign-keys,Php,Mysql,Foreign Keys,我有多个表连接在一起,由几个不同的外键见附件图片。 我正在尝试插入到projects表中。我一直试图通过下面的代码来实现这一点,但它不起作用。现在我得到一个错误,说客户、项目经理都没有值。这是有道理的,因为我没有在插入中包含它们,但它们不是自动递增的,而且我也不能只向这些字段添加随机int,因为这也会引发错误。从技术上讲,如果我将client_id_fk和project_manager_id_fk设置为NULL,那么它可以工作,但是其他表中没有数据……请帮助 $sql1 = "IN

我有多个表连接在一起,由几个不同的外键见附件图片。

我正在尝试插入到projects表中。我一直试图通过下面的代码来实现这一点,但它不起作用。现在我得到一个错误,说客户、项目经理都没有值。这是有道理的,因为我没有在插入中包含它们,但它们不是自动递增的,而且我也不能只向这些字段添加随机int,因为这也会引发错误。从技术上讲,如果我将client_id_fk和project_manager_id_fk设置为NULL,那么它可以工作,但是其他表中没有数据……请帮助


$sql1 = "INSERT INTO PROJECTS (Project_Name, StartDate) VALUES( '".$_POST["Project_Name"]."','".$_POST["StartDate"]."')";
$sql2 = "INSERT INTO CLIENTS(Client_Name, Client_Email, Client_Phone) VALUES ('".$_POST["Client_Name"]."','".$_POST["Client_Email"]."','".$_POST["Client_Phone"]."')";
$sql3 = "INSERT INTO PROJECT_MANAGERS(ProjectManager_Name,Project_Manager_Email, Project_Manager_Phone) VALUES ('".$_POST["ProjectManager_Name"]."','email', 'phone')";     
$sql4 = "INSERT INTO TYPE_OF_WORK(TypeOfWork) VALUES ('".$_POST["TypeOfWork"]."')";
模式:

-将数据插入从属表 在从属_1列_1值“值_1”中插入; 在从属_2列中插入_2值'VALUES_2'; -将数据插入主表, -从从属服务器查询FK值 -使用上面插入的值 -作为过滤条件 插入主列\u main、fk\u列\u 1、fk\u列\u 2 选择'values_main',slave_1.id,slave_2.id 从从从机_1中选择id,其中列_1='values_1'从机_1 从slave_2中连接SELECT id,其中列_2='values_2'slave_2
如果最后一次插入中的某些子查询可能返回超过1行,则将此子查询中的输出列包装到MAX函数中,您将收到最后一行匹配的id,即刚刚插入的id。

请后退一步,考虑您正在建模的关系。您已经告诉MySQL,一个项目有一个客户和一个项目经理;这是有道理的。然后您尝试插入仅包含以下信息的项目:

INSERT INTO PROJECTS (Project_Name, Start_Date) ...
您遇到的错误是问您该项目是为哪个客户开发的,谁是项目经理?这是只有你才能知道的

如果是新客户,则需要在项目之前插入该客户;如果是新的项目经理,您也需要在项目之前插入。插入后,您需要获取他们的ID,例如使用。 如果是现有客户机和/或项目经理,则需要根据应用程序中的逻辑查找他们的ID。 拥有这两个ID后,可以创建项目:

INSERT INTO PROJECTS (Project_Name, Start_Date, Client_Id, Project_Manager_Id) ...
这是错误的:

$sql1 = "INSERT INTO PROJECTS (Project_Name, StartDate) VALUES( '".$_POST["Project_Name"]."','".$_POST["StartDate"]."')";
$sql2 = "INSERT INTO CLIENTS(Client_Name, Client_Email, Client_Phone) VALUES ('".$_POST["Client_Name"]."','".$_POST["Client_Email"]."','".$_POST["Client_Phone"]."')";
$sql3 = "INSERT INTO PROJECT_MANAGERS(ProjectManager_Name,Project_Manager_Email, Project_Manager_Phone) VALUES ('".$_POST["ProjectManager_Name"]."','email', 'phone')";     
$sql4 = "INSERT INTO TYPE_OF_WORK(TypeOfWork) VALUES ('".$_POST["TypeOfWork"]."')";
因为您试图将数据库中不存在的client.id和project_manager.id插入到项目中。因此,如果您使用,上述内容实际上应该这样写:


我到底在围绕MAX函数包装什么?一切正常,但正如你所预测的,我有时会收到超过一行。非常感谢。我不知道为什么MAX在这里会是正确的选择;如果有多个从属表的候选项,则不是最佳名称!这表明WHERE子句不够精确,或者您在建模数据时出错了。@IMSoP如果您有多个候选对象,那么您的从属表中有两行仅在一列中不同,但这是不合逻辑的。我到底在围绕MAX函数包装什么?MAXid而不是id。@Akina就像我说的,解决方法是修复where子句,以提及不同的列,或者删除其中一行(如果它们是完全重复的),而不是对id使用没有意义的数学运算。@IMSoP不看你的-如果是新客户机,你需要在项目之前插入它;如果是新的项目经理,您也需要在项目之前插入。一旦您插入了它们,您需要获取它们的ID,例如,使用LAST_INSERT_ID函数。-如果是现有客户机和/或项目经理,则需要根据应用程序中的逻辑查找他们的ID。这是完全相同的-除了1您的解决方案使用额外的查询和额外的中间PHP变量2我的解决方案没有连接重置问题。请在代码问题中给出-cut&paste&runnable代码,包括作为代码输入的最小代表性示例;期望和实际输出,包括逐字记录错误消息;标签和版本;清晰的说明和解释。尽可能少地给出代码,即显示为OK的代码,并通过显示为not OK的代码进行扩展。调试基础。对于包含DBMS和DDL(包括约束和索引)的SQL,请输入格式化为表的代码。暂停总体目标的工作,在第一个表达中删去代码,不要给出你的期望,说出你的期望以及为什么。请。给出你所需要的&把它和你的问题联系起来。仅将图像用于不能表示为文本或扩充文本的内容。在图像中包含图例/图例和说明。更改插入交换$sql1和$sql3的顺序时,必须先添加客户端和产品管理器,才能添加项目。您的代码对用户开放。不要通过将字符串粘在一起来生成查询。相反,请与一起使用。这是常见问题解答。在考虑发帖之前,请阅读您的课本和/或手册,并用谷歌搜索任何错误消息 或者你的问题/问题/目标的许多清晰、简洁和精确的措辞,有或没有你的特定字符串/名称和网站:stackoverflow.com&tags;阅读许多答案。如果你发布一个问题,用一句话作为标题。反思你的研究。请参见文本上方的投票箭头(&S)。
$link = mysqli_connect('localhost', 'my_user', 'my_password', 'my_db');

/* check connection */
if (!$link) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

// First add the client in case the table is completely empty
$stmt = mysqli_prepare($link, "INSERT INTO clients(name, email, phone) VALUES (?,?,?);");
mysqli_stmt_bind_param($stmt, 'sss', $_POST["Client_Name"], $_POST["Client_Email"], $_POST["Client_Phone"]);
/* execute prepared statement */
mysqli_stmt_execute($stmt);
/* close statement and connection */
mysqli_stmt_close($stmt);

// Then add the project_manager in case the table is completely empty
$stmt = mysqli_prepare($link, "INSERT INTO project_managers(name, email, phone) VALUES (?,?,?);");
mysqli_stmt_bind_param($stmt, 'sss', $_POST["ProjectManager_Name"], 'email', 'phone');
/* execute prepared statement */
mysqli_stmt_execute($stmt);
/* close statement and connection */
mysqli_stmt_close($stmt);

// Also add the type_of_work in case the table is completely empty
$stmt = mysqli_prepare($link, "INSERT INTO type_of_work(TypeOfWork) VALUES (?);");
mysqli_stmt_bind_param($stmt, 's', $_POST["TypeOfWork"]);
/* execute prepared statement */
mysqli_stmt_execute($stmt);
/* close statement and connection */
mysqli_stmt_close($stmt);

// Finally add your project
$stmt = mysqli_prepare($link, "INSERT INTO projects (project_name, start_date, client_id, project_manager_id) SELECT ?,?,client.id,project_managers.id FROM client,project_managers WHERE client.name = ? AND client.email = ? AND client.phone = ? AND project_managers.name = ?;");
mysqli_stmt_bind_param($stmt, 'ssssss', $_POST["Project_Name"],$_POST["StartDate"],$_POST["Client_Name"], $_POST["Client_Email"], $_POST["Client_Phone"],$_POST["ProjectManager_Name"]);
/* execute prepared statement */
mysqli_stmt_execute($stmt);
/* close statement and connection */
mysqli_stmt_close($stmt);

/* close connection */
mysqli_close($link);