MySql - 替换“array”-value

时间:2014-05-20 12:29:53

标签: php mysql arrays

我在列中有“1,3,6,17”等记录,并使用以下内容删除,例如来自他们的“6”:

$sql = "SELECT SeId, SeCatId FROM series WHERE FIND_IN_SET(:catid,SeCatId)";
$stmt = $dbh->prepare($sql);
$stmt -> bindParam('catid',$id);
$stmt->execute();
$result = $stmt->FetchAll();
foreach($result as $row){
  $seid = $row['SeId'];
  $ids = explode(",",$row['SeCatId']);
  $i = 0;
  foreach($ids as $catid) {
    if($catid===$id){unset($ids[$i]);}
    $i++;
  }
  $ids = implode(",",$ids);
  $sql = "UPDATE series SET SeCatId = :catid WHERE SeId = :id";
  $stmt = $dbh->prepare($sql);
  $stmt -> bindParam(':catid',$ids);
  $stmt -> bindParam(':id',$seid);
  $stmt->execute();
}

工作正常,但似乎很复杂。有没有更简单的方法来做同样的事情?

4 个答案:

答案 0 :(得分:1)

如果您使用更好的数据库设计,那将很容易。不是将ID存储在逗号分隔的字符串中,而是创建一个新表来处理关联。

series_cat_assoc ( SeId, SeCatId )

使用它,如果一个系列有多个类别,您可以插入多行。这使得创建,更新删除变得容易。例如,从给定系列中删除给定类别:

$sql = "SELECT series_cat_assoc WHERE SeCatId = :catid and SeId = :seid)";

答案 1 :(得分:0)

您可以使用array_diff并执行类似

的操作
$stmt->bindParam(':catid', implode(',', array_diff(explode(",", $row['SeCatId']), array('6')));

但你的问题不是PHP,而是你的SQL架构。你不应该在同一个字段中有“数组”值(阅读database normalization以了解原因)。归一化是为了避免这些问题。您应该有一个单独的模式,其中SeId和SeCatId为列,SeId是您的系列表的外键,SeCatId是一个唯一的整数(不是数组)。

您应该有以下行:

SeId | SeCatId
1    | 1
1    | 3
1    | 6
1    | 7

然后删除一个类别只是一个简单的DELETE语句问题。

答案 2 :(得分:0)

我不知道在算法上是否有更高效的方式,但根据我对您的代码的理解,您可以使用正则表达式更清晰。替换这个:

foreach($result as $row){
$seid = $row['SeId'];
$ids = explode(",",$row['SeCatId']);
$i = 0;
foreach($ids as $catid) {
  if($catid===$id){unset($ids[$i]);}
  $i++;
}
$ids = implode(",",$ids);

有了这个:

$ids = str_replace(','.$id.',', ',', $row['SeCatId']);
$ids = preg_replace('/(^|,)('.$id.')(,|$)/', "{$0}{$2}", $ids);

答案 3 :(得分:0)

我强烈强烈建议您使用关联/联结表来存储数据。但有时候,您可能会遇到格式错误的数据库,并且您必须执行此类操作。如果是这样,你可以这样做:

select replace(trim(replace(replace(concat(',', SeCatId, ','), concat(',', 6, ','), ','), ',', ' '), ' ', ',')

这个想法如下:

  1. 在列表的开头和结尾添加逗号,因此所有元素都被分隔符
  2. 包围
  3. 替换逗号包围的值(因此" 16"不受影响)
  4. 用空格替换所有逗号
  5. 使用trim()删除第一个和最后一个空格
  6. 用逗号替换空格
  7. 您可以在一次更新中执行此操作:

    update table t
        set SeCatId = replace(trim(replace(replace(concat(',', SeCatId, ','), concat(',', 6, ','), ','), ',', ' '), ' ', ',')
        where concat(',', SeCatid, ',') like concat('%,', 6, ',%');