Как добавить первичный ключ с автоинкрементом в другое поле в той же таблице? - PullRequest
5 голосов
/ 30 ноября 2011

Я использую yii активных записей для mysql , и у меня есть таблица, в которой есть поле, к которому необходимо добавить первичный ключ той же таблицы. Первичный ключ - это поле с автоматическим приращением, поэтому я не могу получить доступ к первичному ключу перед сохранением.

$model->append_field = "xyz".$model->id; // nothing is appending
$model->save();
$model->append_field = "xyz".$model->id; //id is now available

Как мне это сделать?
Я знаю, что могу обновить сразу после вставки, но есть ли лучший способ?

Ответы [ 3 ]

3 голосов
/ 30 ноября 2011

Еще несколько обходных путей:

Это почти твой подход;)

$model->save();
$model->append_field = "xyz".$model->id; //id is now available
$model->save();

Но вы можете переместить эту функцию в поведение с помощью специального метода afterSave (), обратите внимание, что вам нужно позаботиться о том, чтобы не зацикливать событие.

Или просто напишите для него геттер

function getFull_append_field(){
  return $this->append_field.$this->id;  
}

но тогда вы не сможете использовать его в операторе SQL, если только вы не создадите там атрибут с помощью CONCAT () или чего-то подобного.

3 голосов
/ 30 ноября 2011

Вашей записи присваивается значение id только после выполнения оператора INSERT. Невозможно определить, что это id до INSERT, поэтому придется выполнить UPDATE со значением объединенного поля после INSERT.

Вы можете написать хранимую процедуру или триггер в MySQL, чтобы сделать это для вас, поэтому ваше приложение выполняет один SQL-оператор для этого. Однако вы просто перемещаете логику в MySQL, и в конце происходят INSERT и UPDATE.

2 голосов
/ 01 декабря 2011

Любой, кто придет к этому вопросу, может быть заинтересован в том, как именно я его реализовал, поэтому вот код:

//in the model class
 class SomeModel extends CActiveRecord{
  ...
  protected function afterSave(){
     parent::afterSave();
     if($this->getIsNewRecord()){
        $this->append_field=$this->append_field.$this->id;
        $this->updateByPk($this->id, array('append_field'=>$this->append_field));
     }
  }
 }

Одним из способов избежать зацикливания события (как упомянуто @schmunk) было использование saveAttributes(...) внутри метода afterSave(), но saveAttributes (...) проверяет isNewRecord , и вставляет значение только в том случае, если это новая запись, поэтому мы должны использовать setNewRecord(false); перед вызовом saveAttributes (...).Я обнаружил, что saveAttributes (...) на самом деле вызывает updateByPk(...), поэтому я непосредственно использовал updateByPk (...).

...