2013-03-29 80 views
0

因此,我編寫了這個方法,用於我的chrome插件(它執行ajax請求來運行此方法),並且當它運行時,file_put_contents顯示插入內容的id,但那麼當它到達insert ignore into songs時,它將爲artist_id輸入0。我不知道爲什麼...有人可以幫助我找到我要出錯的地方嗎?由於某種原因,PDO插入一個id爲

<?php 
public function saveLyrics($artist, $title, $lyric){ 
    $this->db->query("insert ignore into artists (artist_name) value (:artist)", array("artist" => $artist)); 
    $artist_id = (int)$this->db->insertID(); 
    file_put_contents(__DIR__ . "/../process/page", "artist id: $artist_id"); 
    //return; 
    if($artist_id == 0){ 
     $artist_id = (int)$this->db->getOne("select artist_id from artists where artist_name = :artist", array("artist" => $artist)); 
    } 
    if($artist_id == 0){ 
     return false; 
    } 
    $this->db->query("insert ignore into songs (artist_id, song_name) values (:aid, :title)", array("aid" => $artist_id, "title" => $title)); 
    $song_id = (int)$this->db->insertID(); 
    if($song_id == 0){ 
     $song_id = (int)$this->db->getOne("select song_id from songs where artist_id = aid and song_name = :title", array("aid" => $artist_id, "title" => $title)); 
    } 
} 

PDO包裝:

<?php 

/** 
* @property PDO $pdo Description 
* @property PDOStatement $sql Description 
*/ 
class DB{ 

    protected $sql = null; 
    protected $pdo = null; 

    public function connect(){ 
     $this->pdo = new PDO("mysql:dbname=envne;host=xxx", "xxx", "xxx"); 
    } 

    public function query($query, $params = array()){ 
     if($this->pdo === null){ 
      $this->connect(); 
     } 
     $this->sql = $this->pdo->prepare($query); 
     foreach($params as $key => $value){ 
      $this->sql->bindParam($key, $value); 
     } 
     $this->sql->execute(); 
     if(!$this->sql) 
      return false; 
     return true; 
    } 
    public function insertID(){ 
     return (int)$this->pdo->lastInsertId(); 
    } 

    public function getAll($query, $params = array()){ 
     $this->query($query, $params); 
     return $this->sql->fetchAll(); 
    } 

    public function getOne($query, $params = array()){ 
     $this->query($query, $params); 
     return $this->sql->fetchColumn(); 
    } 

} 

藝術家:

mysql> describe artists; 
+-------------+------------------+------+-----+-------------------+----------------+ 
| Field  | Type    | Null | Key | Default   | Extra   | 
+-------------+------------------+------+-----+-------------------+----------------+ 
| artist_id | int(10) unsigned | NO | PRI | NULL    | auto_increment | 
| artist_name | char(50)   | YES | UNI | NULL    |    | 
| add_date | timestamp  | YES |  | CURRENT_TIMESTAMP |    | 
+-------------+------------------+------+-----+-------------------+----------------+ 
3 rows in set (0.00 sec) 

歌曲:

mysql> describe songs; 
+------------+------------------+------+-----+-------------------+----------------+ 
| Field  | Type    | Null | Key | Default   | Extra   | 
+------------+------------------+------+-----+-------------------+----------------+ 
| song_id | int(10) unsigned | NO | PRI | NULL    | auto_increment | 
| artist_id | int(11) unsigned | YES | MUL | NULL    |    | 
| album_id | int(11)   | YES | MUL | NULL    |    | 
| song_name | char(50)   | YES |  | NULL    |    | 
| track_id | int(11)   | YES |  | NULL    |    | 
| date_added | timestamp  | NO |  | CURRENT_TIMESTAMP |    | 
+------------+------------------+------+-----+-------------------+----------------+ 
6 rows in set (0.01 sec) 
+0

你有一個'auto_increment'列在表中?是否因重複鍵而忽略插入? – MichaelRushton

+0

表格定義請 – fredrik

+0

對不起,我的意思是'artist_id'而不是'song_id'。 –

回答

0

我決定直接把標識到查詢,而作品。

$artist_id = (int)$this->db->insertID(); 
$this->db->query("insert ignore into songs (artist_id, song_name) values ($artist_id, :title)", array("title" => $title)); 

正在使用一個問號,而不是

$artist_id = (int)$this->db->insertID(); 
$this->db->query("insert ignore into songs (artist_id, song_name) values (?, ?)", array($artist_id, $title)); 
+0

嗯,那很奇怪。 – hjpotter92

+0

我知道......我以前從來沒有遇到這個問題...... –

+0

嗯也許有用,但這絕對不是好習慣。您錯過了查詢綁定參數的要點。 – bestprogrammerintheworld

-1

你的佔位符定義不正確工作的另一種方法:(您錯過了冒號) 我會做這樣的事情:

public function saveLyrics($artist, $title, $lyric){ 
    $this->db->query("insert ignore into artists (artist_name) value (:artist)", array(":artist" => $artist)); 
    $artist_id = (int)$this->db->insertID(); 
    file_put_contents(__DIR__ . "/../process/page", "artist id: $artist_id"); 
    //return; 
    if($artist_id == 0){ 
     $artist_id = (int)$this->db->getOne("select artist_id from artists where artist_name = :artist", array(":artist" => $artist)); 
     return false; 
    } 
    $this->db->query("insert ignore into songs (artist_id, song_name) values (:aid, :title)", array(":aid"=>$artist_id, ":title"=>$title)); 
    $song_id = (int)$this->db->insertID(); 
    if($song_id == 0){ 
     $song_id = (int)$this->db->getOne("select song_id from songs where artist_id = :aid and song_name = :title", array(":aid"=>$artist_id, ":title"=>$title)); 
    } 
} 

考慮看看您的PDO,包裝你有這樣的代碼:

if(!$this->sql) 
    return false; 

因此,您永遠不會注意到實際的錯誤。我猜這個錯誤是關於佔位符的。 (如果$this->db->query("insert ignore into songs (...失敗$ song_id只會在執行查詢時出錯)。

改爲使用異常並捕獲錯誤,那會更好。

我還注意到:

$song_id = (int)$this->db->insertID(); 

將投值的兩倍,首先在上面的代碼中,然後在實際的功能insertID()在PDO-包裝。也許這也是一個需要考慮的問題。

+0

如果downvote請評論 - 否則downvote是毫無意義的。 – bestprogrammerintheworld

0

我剛剛遇到同樣的問題:即使ID字段設置爲AUTO_INCRIMENT,新插入的項目也會得到0的ID。

我找到的解決方案與您的解決方案非常相似。使用你的代碼,這是我們所得到的:

$this->db->query("insert ignore into songs (artist_id, song_name) values (LAST_INSERT_ID(), :title)", array("title" => $title)); 

正如你所看到的,我換成$artist_id = (int)$this->db->insertID();$artist_id與SQL函數LAST_INSERT_ID()

我希望這可以幫助別人有一天:)

相關問題