Php 使用PDO内部循环插入
很抱歉问了一些基本的问题,但我对这个错误感到很沮丧。请检查是否需要更正某些内容。如图所示,我试图将数据保存到表A中,从表B中获取数据。保存前,它会检查表B中的数据是否不在表A中,并将其插入 这是我的代码:Php 使用PDO内部循环插入,php,pdo,Php,Pdo,很抱歉问了一些基本的问题,但我对这个错误感到很沮丧。请检查是否需要更正某些内容。如图所示,我试图将数据保存到表A中,从表B中获取数据。保存前,它会检查表B中的数据是否不在表A中,并将其插入 这是我的代码: $sql1="select * from B where status=2"; $q1=$this->pdo->query($sql1); $q1->execute(); $result1=$q1->fetchAll(PDO::FETCH_ASSOC); foreac
$sql1="select * from B where status=2";
$q1=$this->pdo->query($sql1);
$q1->execute();
$result1=$q1->fetchAll(PDO::FETCH_ASSOC);
foreach ($result1 as $row) {
$sql2="select * from A where idB='".$row['idB']."'";
$q2=$this->pdo->query($sql2);
$q2->execute();
$result2=$q2->fetchAll();
if(empty($result2)){
$data = ['idB' => $row['idB'],'name' => $row['name'];
$s_inreg="insert into A(idB,name) values(:idB,:name)";
$stmt=$this->pdo->prepare($s_inreg);
$ret=$stmt->execute($data);
}
}
假设有100个数据,只有10个数据存储成功,其余的数据保存失败。假设您使用的是MySQL数据库,您可以使用以下语法通过一个查询完成此操作 在“idB”中插入“名称”` 从B中选择'idB','name' 其中B.status=2 而且不存在 从列表中选择1 其中A.idB=B.idB
在这里,我缩小了你的代码,或者至少是那些真正做事情的代码
$result1 = $this->pdo->query('
SELECT
B.idB,
B.name
FROM
B
LEFT JOIN
A ON A.idB=B.idB
WHERE
B.status=2 AND IS NULL A.ibB
')->fetchAll(PDO::FETCH_ASSOC);
$stmt = $this->pdo->prepare('
INSERT INTO
A(idB,name) VALUES (:idB,:name)'
);
foreach ($result1 as $row) $stmt->execute($row);
假设您所做的是正确的,让我们看看连接
select * from B where status=2
select * from A where idB='".$row['idB']."'
//and the results of A are $row
$row['name'] //<-- dont forget this field
当我们加入他们时:
select
B.idB,B.name
from
B
LEFT JOIN #left JOIN
A ON A.idB=B.idB
WHERE
B.status=2
AND
IS NULL A.ibB #records from B where no A.idB exists.
正如评论中指出的那样:
您基本上需要B中的所有记录,这些记录没有与a中的记录匹配的记录
为此,我们可以使用左连接。如果联接表B的左侧有联接记录,则将返回联接表B左侧的所有记录
然后我们只需要保留左侧B中A.ibB值为null的记录,我们可以使用null A.ibB
这些缺失的记录是我们希望在末尾插入的记录:
然后让我们看看PDO代码:
$q1=$this->pdo->query($sql1);
/// $q1->execute(); <--------------------- no need for this
$result1=$q1->fetchAll(PDO::FETCH_ASSOC);
如果您将PDO设置为抛出异常,那么您就不必担心if失败时返回FALSE,因为它只会抛出异常
就像我们只使用一次SQL字符串一样,我们可以直接将其放入,然后去掉$sql1。插入查询也是如此:
$stmt = $this->pdo->prepare('INSERT INTO A(idB,name) VALUES (:idB,:name)');
foreach ($result1 as $row) $stmt->execute($row);
但是有一两个,注意到。在这里,因为我们将从第一个查询中提取的内容缩减为只需要的内容,并且所有内容的名称都相同,所以我们可以将$row直接放入execute。另一件需要注意的事情是在循环之外准备查询。我们可以根据需要多次重复使用PDO语句,DB只需要第一次解释SQL,这为我们节省了一点性能
萨默里
如果便于阅读,请保留局部变量。我喜欢摆脱它们,因为我不太喜欢打字,因为我写了很多代码,所以我尽量少写,以完成这项工作。但是,我已经做了很长时间了,所以我可以相当容易地阅读更复杂的代码
我只是想用这种方式来展示它,因为我认为它在许多例子中都没有得到很好的体现,比如你可以在多大程度上减少你的代码,并且仍然让它做同样的事情。要看的代码越少,调试的代码就越少
干杯。既然$result2从未使用过,那么$result2有什么意义呢?请准备好您的查询,因为它在PDO中非常简单。@ArtisticPhoenix$result2用于if empty$result2您使用的是什么数据库?MySQL或其他什么?我认为您的连接逻辑与OP想要的相反。你的查询将选择所有在a中有匹配idB的B记录。哈哈,你的右边@Phil-我把我的阅读障碍归咎于此。我需要一个带isnull的左连接,至少我认为是这样,在我的头脑中弄清楚了。感谢伟大的分析,这就是我需要的。顺便说一句,正如您已经演示的,当表位于同一数据库中时,确实可以使用JOIN。但在相同的情况下,如果两个表(如A和B)位于不同的数据库中,该怎么办?当然,JOIN对我们来说相当困难。Mysql实际上可以在不同数据库中的两个表之间进行连接。并非所有数据库都能做到这一点,因此通常不鼓励这样做。您只需要包括数据库,从database1.table中选择a.*,b.*作为联接database2.table作为b。。。。不要告诉任何人,但实际上我一直都这么做。但这是因为我们集成了3个不同的系统,2个是第三方产品,1个是我创建的,因此我无法修改第三方应用程序的数据库,而将其放入我的应用程序需要不必要的维护。是的,在此之前,感谢@ArtisticPhoenix为您提供的帮助。
$result1 = $this->pdo->query($sql1)->fetchAll(PDO::FETCH_ASSOC);
$stmt = $this->pdo->prepare('INSERT INTO A(idB,name) VALUES (:idB,:name)');
foreach ($result1 as $row) $stmt->execute($row);