理想的には NULL として返される必要があるプライマリ/外部キーを除いて、結合されたテーブルから行をデフォルト値で新しく挿入されたかのように返す、より単純なクエリを探しています。これは、1 つのデータ入力フォームを使用して、新しいエントリを追加したり、既存のエントリを編集したりできるようにするためです。
CodeIgniter、DB_ActiveRecord クラス、および postgre DB ドライバーを使用しています。
私が思いついた関数を以下に示します。簡略化したい部分に「最適化の方法」というコメントを付けました。
public function get_entry()
{
$id = $this->input->post('id');
if ($id) {
// Get existing entry from joined tables.
$query = $this->db
->join('b', 'a.id = b.id')
->get_where('a', array('a.id' => $id));
} else {
// Get a new "default" entry from joined tables.
// How to optimize? Ideally it would:
// 1. Not need a transaction.
// 2. Not insert (causes holes in the id sequence.)
// 3. Not use a PHP trick of overlaying same-named results.
$this->db->trans_begin();
// Note: I modified insert() so that empty array gives "DEFAULT VALUES"
// and 3rd parameter gives "RETURNING ..."
$query = $this->db
->insert('a', array(), 'id');
if ($this->db->trans_status() and $query->num_rows()) {
$id = $query->row()->id;
$query = $this->db
->insert('b', array('id' => $id));
if ($this->db->trans_status() and $query) {
$query = $this->db
// Note: This trick overlays NULL onto value in id
->select('*, NULL AS id')
->join('b', 'a.id = b.id')
->get_where('a', array('a.id' => $id));
}
}
// Note: Trash the temporary insert.
$this->db->trans_rollback();
}
if ($query and $query->num_rows()) {
return $query->result();
}
return FALSE;
}