2011-07-12 41 views
3

我有這些表:任何優雅的解決方案如何使插入多對多的表?

  • 標籤 - 包含標籤名稱和ID(TAG_ID,標籤)
  • TagReview - 鏈接標籤和評論(REVIEW_ID,TAG_ID)
  • 回顧與表 - 持有評論。 (Review_ID,content,...)

當我在添加或編輯評論時做了插入操作。 在我的變量表類從擴展的Zend_Db_Table ... 插入工作了一些案件,但然後用SQL錯誤失敗「SQLSTATE [23000]:完整性約束衝突:1452」

public function insertTags($reviewId, $tagList) { 
    $reviewTag = new Application_Model_DbTable_ReviewTag; 
    $tags = explode(self::SEPERATE, $tagList); 

    foreach ($tags as $tag) { 
     $tag = trim($tag); 
     $tagRow = $this->fetchRow(array('tag = ?' => $tag)); 
     if ($tagRow == null) { 
      $tagId = $this->insert(array(
       'tag' => trim($tag) 
      )); 
      $reviewTag->insert(array(
       'Tag_ID'  => $tagId, 
       'Review_ID'  => $reviewId,  
      )); 
     } 

    } 
} 
+0

Ddi你得到違規插入標籤或reviewTag? – prodigitalson

+0

插入到reviewTag表 –

回答

0

我已經通過此代碼解決了我的解決方案。如果在編輯標籤已被刪除或添加時也處理該問題。

/** 
* Insert the tags. 
* @param reviewId int review which the tags belongs. 
* @param tagList string tags with seperated coma or space. 
*/ 
public function insertTags($reviewId, $tagList) { 
    // The join table to solve many-to-many relation 
    $reviewTag = new Review_Model_DbTable_ReviewTag; 
    $tags = explode(self::SEPERATE, $tagList); 

    // Go through all the tags 
    foreach ($tags as $tag) { 
     $tag = trim($tag); 

     // Check if already in Tag table 
     $tagRow = $this->fetchRow(array('tag = ?' => $tag)); 
     if ($tagRow == null) { 
      // It's new tag create new tag 
      $tagId = $this->insert(array(
       'tag'    => trim($tag) 
      )); 
      // Add the the id's to join table 
      $reviewTag->insert(array(
       'Tag_ID'   => $tagId, 
       'Review_ID'   => $reviewId,  
      )); 
     } else { 
      // Tag is already in database use the id and check the uniquness 
      $unique = $reviewTag->fetchRow(array(
       'Review_ID = ?'  => $reviewId, 
       'Tag_ID = ?'  => $tagRow->Tag_ID 
      )); 
      if ($unique == null) { 
       $reviewTag->insert(array(
        'Tag_ID'  => $tagRow->Tag_ID, 
        'Review_ID'  => $reviewId,      
       )); 
      } 

     } 
    } 
    $this->deleteTags($tags, $this->getOnlyTags($reviewId), $reviewId); 
} 

/** 
* Delete tags from table which are listed in $tags array. 
* @param mixed $tags array 
* @param mixed $userInserted array 
* @param int $reviewId 
*/ 
public function deleteTags($tags, $userInserted, $reviewId) { 
    $diffTags = array_diff($tags, $userInserted); 
    $reviewTag = new Review_Model_DbTable_ReviewTag; 

    foreach ($diffTags as $tag) { 
     $tagId = $this->fetchRow(array('tag = ?' => $tag))->Tag_ID; 
     $reviewTag->delete(array(
      'Review_ID = ?' => $reviewId, 
      'Tag_ID = ?' => $tagId, 
     )); 
    } 
} 
/** 
* Get the tags names related to review. 
* @param reviewId int review id 
* @return array name of the tags as string 
*/ 
public function getOnlyTags($reviewId) { 
    $tags = array(); 
    $reviewTags = $this->fetchTags($reviewId); 
    foreach ($reviewTags as $reviewTag) { 
     $tags[] = $reviewTag->tag; 
    } 
    return $tags; 
} 
0

所以問題是:

"SQLSTATE[23000]: Integrity constraint violation: 1452"

如果我不得不採取的猜測沒有一個堆棧跟蹤,我會說,下面一行是問題:我假設你有你的標籤表的唯一約束,以確保重複的標籤AREN」

$tagId = $this->insert(array(
    'tag' => trim($tag) 
)); 

t添加到表。

問題是,這行不應該是一個插入,它應該是一個getTagIDByTag和失敗,插入。 SO,

public function insertTags($reviewId, $tagList) 
{ 
    $reviewTag = new Application_Model_DbTable_ReviewTag; 
    $tags = explode(self::SEPERATE, $tagList); 

    foreach($tags as $tag) 
    { 
     $tag = trim($tag); 
     $tagRow = $this->fetchRow(array('tag = ?' => $tag)); 
     if($tagRow == null) 
     { 
      // FIRST TRY TO GET THE TAG 
      $tagId = $db->fetchCol('SELECT Tag_ID FROM Tag WHERE tag = ?', trim($tag)); 

      // ZEND RETURNS NULL IF THE QUERY DOESN'T RETURN ANYTHING 
      if(is_null($tagId)) 
      { 
       // CREATE THE TAG 
       $tagId = $this->insert(array(
        'tag' => trim($tag) 
       )); 
      } 

      $reviewTag->insert(array(
       'Tag_ID'  => $tagId, // USE THE TAG ID LIKE NORMAL 
       'Review_ID'  => $reviewId,  
      )); 
     } 
    } 
} 

相關問題