Гибрид обновления, удаления и вставки

krafty

new Exception
Гибрид обновления, удаления и вставки

Постановка задачи.
Есть таблица с двумя полями и уникальным индексом, построенным по этим двум полям. Массив добавляемых данных представляет собой пары const-var1, const-var2,... . Необходимо вставить эти данные таким образом:
если в таблице уже есть такая пара значений, то игнорировать. В таблице после вставки должна быть точная копия добавляемых данных для данного значения поля (const), т.е. ничего лишнего.
Простой INSERT IGNORE в этом случае не подойдет, поскольку останутся старые поля.
Конечно выход есть очевидный выход:
DELETE FROM tbl WHERE f1=$const
INSERT INTO ...............
Может есть у кого-нибудь конструктивные мысли?
 

baev

‹°°¬•
Команда форума
Посмотрите в MySQL-мануале REPLACE (не команду, а строковую функцию!) и REGEXP.
 

Elens

Guest
если решили проблему, поделитесь идеей. у меня очень похожая задача, только полей в таблице много, обновляется из текстового файла. Как полностью переписывать таблицу, не прибегая к DELETE и INSERT.
 

krafty

new Exception
чисто на sql решить не получилось.
вобщем у меня есть текстареа. в нем через пробельные символы перечислены элементы. пользователь редактирует произвольным образом. задача следующая: если элемент остался после редактирования, то сохраняем его в базе (вместе с id и другими полями). если добавился новый - добавляем в базу. если какой-то исчез - удаляем из базы. Задача вобщем-то и не такая тривиальная, как показалась мне на первый взгляд.
вобщем вот че я наваял
простите за mssql_* (забыл поменять:))
PHP:
//заменяем знаки абзаца на пробелы  
  $str=str_replace("\r"," ",$_POST['textarea']);
  $str=str_replace("\n"," ",$str);
  $str=str_replace("  "," ",$str);
  //в массив
  $objects=explode(" ",$str);
  //удаляемы ведущие и ведомые пробелы и 
  //пустые элементы массива
  foreach ($objects as $key=>$v) {
    $v=trim($v);  
    if ($v=="") unset($objects[$key]);
  }
  //а теперь нужно сделать следующее: после редактирования списка в таблице
  //объекты, которые остались в списке, должны сохраниться; которые добавились в 
  //список - добавиться и в таблицу; которые отсутствуют в списке, но присутствуют
  //в таблице - удалиться из таблицы. Кроме того, удаленные из таблицы объекты
  //должны быть удалены из таблицы отношений permiss_obj. 
  $res=mssql_query("SELECT * FROM objects");
  while ($f=mssql_fetch_array($res)) $obj_base[$f[0]]=$f[1];
  if (!empty($obj_base)) {
    foreach ($obj_base as $key=>$v) 
      if (!in_array($obj_base[$key],$objects)) 
        //номера записей в таблице для удаления  
        $id_del[]=$key;
    //то что нужно добавить (считается как теоретико-множественная разница между
    //$objects и объединением $objects и $obj_base)
    $arr_add=array_diff($objects,array_intersect($objects,$obj_base));
  }  
  else $arr_add=$objects;
  if (!empty($id_del)) {
    $q=implode(' OR id=',$id_del);
    //удаляем
    mssql_query("DELETE FROM objects WHERE id=$q");
    mssql_query("DELETE FROM permiss_obj WHERE id_obj=$q");
  }  
  //добавляем
  foreach ($arr_add as $v)
    mssql_query("INSERT INTO objects (script_name) VALUES ('$v')");
-~{}~ 22.11.05 17:06:

кто знает более рациональное решение - милости просим!
 
Сверху