Php 使用新值更新连接表
我有一个一对多的表(实际上应用程序将实际使用多对多,但这与我的问题无关)。假设两列具有以下值:Php 使用新值更新连接表,php,mysql,sql,pdo,Php,Mysql,Sql,Pdo,我有一个一对多的表(实际上应用程序将实际使用多对多,但这与我的问题无关)。假设两列具有以下值: c1 c2 2 3 4 1 4 3 4 4 6 4 对于给定的c1值4,我想用数组[1,2,4,6]中的c2值更新表。因此,我的表格如下(注意,记录4,2和4,6已添加,记录4,3不再存在,记录4,1和4,4保持不变): 实现这一目标的最佳方式是什么?我“可以”首先查询数据库以选择c1=4的现有值,然后使用array\u intersect()来标识添加和删除的记录,并根据需要插
c1 c2
2 3
4 1
4 3
4 4
6 4
对于给定的c1值4,我想用数组[1,2,4,6]中的c2值更新表。因此,我的表格如下(注意,记录4,2和4,6已添加,记录4,3不再存在,记录4,1和4,4保持不变):
实现这一目标的最佳方式是什么?我“可以”首先查询数据库以选择c1=4的现有值,然后使用
array\u intersect()
来标识添加和删除的记录,并根据需要插入/删除,但是,这似乎太过分了。我知道这很旧,但我花了一段时间才找到答案,这个问题在谷歌排名很高。
我找到了以下代码并对其进行了修改:
INSERT IGNORE INTO my_table VALUES (1,1), (1,2), (1,3);
DELETE FROM my_table WHERE c1 NOT IN (1,2,3) AND my_table = 1;
源代码的来源:
我修改后用于PHP变量和PDO循环的代码:
$a_id = $my_main_id //this would be c1 in the above question
//Set Variable From Post
$var_1 = isset($_POST['var_1']) ? $_POST['var_1'] : '';
$var_2 = isset($_POST['var_2']) ? $_POST['var_2'] : '';
//etc, etc, etc
//put variables into array
$data = array('var_1'=>$var_1, 'var_2'=>$var_2, 'var_3'=>$var_3, 'var_4'=>$var_4, 'tarp_5'=>$tarp_5);
//get count of variable that contain data and not empty
$data_array_count = 0;
foreach ($data as $column => $value) {
if($value != '') {
$data_array_count = ++$data_array_count;
}
}
//if contains atleast one variable run update code
if($data_array_count != 0) {
//loops through and inserts each varible in array
foreach ($data as $column => $value) {
//ignores variables without any data
if($value != '') {
$insert = $db->prepare("INSERT IGNORE my_table (a_id, b_id) VALUES (:a_id, :b_id)");
$insert->execute(array(':a_id' => $a_id,
':b_id' => $value ));
}
}
//sets up variables in array to remove any records that need to be deleted
$columns = "";
$holders = "";
foreach ($data as $column => $value) {
if($value != '') {
$columns .= ($columns == "") ? "" : ", ";
$columns .= $column;
$holders .= ($holders == "") ? "" : ", ";
$holders .= ":$column";
}
}
$delete = $db->prepare("DELETE FROM my_table WHERE accessory_id NOT IN ($holders) AND (carrier_id = :a_id)");
//bind value for main id
$delete->bindValue(":a_id", $a_id);
//loop to bind value for each variable stored in array with data
foreach($data as $placeholder => $value) {
if($value != '') {
$delete->bindValue(":" . $placeholder, $value);
}
}
$delete->execute();
}
使用原始问题中的示例,您必须为要更新的每个
c1
id号运行此代码(c1
将相当于我的示例中的$a_id
变量)。可能我遗漏了一些内容,但为什么不删除c1=4的行并根据数组插入记录呢?而不是试图找出哪些行存在、缺少或存在不同的值。@JChao。是的,这是另一种选择。推荐吗?对索引有什么影响?是的,它可能会导致碎片。我想这取决于这类操作发生的频率,以及索引的大小。很抱歉,我最初的想法是一次性操作。
$a_id = $my_main_id //this would be c1 in the above question
//Set Variable From Post
$var_1 = isset($_POST['var_1']) ? $_POST['var_1'] : '';
$var_2 = isset($_POST['var_2']) ? $_POST['var_2'] : '';
//etc, etc, etc
//put variables into array
$data = array('var_1'=>$var_1, 'var_2'=>$var_2, 'var_3'=>$var_3, 'var_4'=>$var_4, 'tarp_5'=>$tarp_5);
//get count of variable that contain data and not empty
$data_array_count = 0;
foreach ($data as $column => $value) {
if($value != '') {
$data_array_count = ++$data_array_count;
}
}
//if contains atleast one variable run update code
if($data_array_count != 0) {
//loops through and inserts each varible in array
foreach ($data as $column => $value) {
//ignores variables without any data
if($value != '') {
$insert = $db->prepare("INSERT IGNORE my_table (a_id, b_id) VALUES (:a_id, :b_id)");
$insert->execute(array(':a_id' => $a_id,
':b_id' => $value ));
}
}
//sets up variables in array to remove any records that need to be deleted
$columns = "";
$holders = "";
foreach ($data as $column => $value) {
if($value != '') {
$columns .= ($columns == "") ? "" : ", ";
$columns .= $column;
$holders .= ($holders == "") ? "" : ", ";
$holders .= ":$column";
}
}
$delete = $db->prepare("DELETE FROM my_table WHERE accessory_id NOT IN ($holders) AND (carrier_id = :a_id)");
//bind value for main id
$delete->bindValue(":a_id", $a_id);
//loop to bind value for each variable stored in array with data
foreach($data as $placeholder => $value) {
if($value != '') {
$delete->bindValue(":" . $placeholder, $value);
}
}
$delete->execute();
}