無責任的爛筆頭

          Concentrate & enjoy!
          posts - 3, comments - 15, trackbacks - 0, articles - 7
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          萬無一失的id獲取方法(MySQL)?

          Posted on 2010-04-11 02:54 BZ 閱讀(469) 評論(0)  編輯  收藏 所屬分類: MySQL
            看代碼:
             public static function saveTheater($theater, $country, $dbConn) {
                      $insertSql = sprintf('INSERT IGNORE INTO theaters(name, address, country, latitude, longitude, tel) VALUES (%s, %s, %s, %f, %f, %s)', 
                                          DBUtils
          ::escape($theater->name, $dbConn), 
                                          DBUtils
          ::escape($theater->address, $dbConn),
                                          DBUtils
          ::escape($country, $dbConn),
                                          
          $theater->latitude, $theater->longitude,
                                          DBUtils
          ::escape($theater->tel, $dbConn));
                      DBUtils
          ::execute($insertSql, $dbConn);
                      
          $theaterId = mysql_insert_id($dbConn);
                      
          if ($theaterId == 0) { //conflict, others saved it. we need get the theater by querying
                          $query = sprintf('SELECT id FROM theaters FORCE INDEX(theaters_I1) WHERE name=%s AND address=%s AND country=%s', 
                                           DBUtils
          ::escape($theater->name, $dbConn), 
                                         DBUtils
          ::escape($theater->address, $dbConn),
                                         DBUtils
          ::escape($country, $dbConn));
                        
          $resultSet = DBUtils::execute($query, $dbConn);
                           
          if ($row = mysql_fetch_assoc($resultSet)) {
                               
          $theaterId = $row['id'];
                           }
                      }
                      
                      
          return $theaterId;
                  }
            這段代碼從邏輯上講,無懈可擊--數據庫中沒有數據的話,插入, 然后獲取自增的id。如果這個值為0, 那么表示數據已經存在數據庫中了,從而執行一個Query操作,取得需要的id。如果從SQL的角度來看,可能執行的兩條SQL是: 

          INSERT IGNORE INTO theaters(name, address, country, latitude, longitude, tel) VALUES ("Vue Cinemas - Cheshire Oaks", "Ellesmere Port, Coliseum Way, Chesire Oaks Outlet Village, South Wirral CH65 9HD, United Kingdom", "GB", 53.306521-2.914062, "0871 224 0240")

          SELECT id FROM theaters FORCE INDEX(theaters_I1) WHERE name="Vue Cinemas - Cheshire Oaks" AND address="Ellesmere Port, Coliseum Way, Chesire Oaks Outlet Village, South Wirral CH65 9HD, United Kingdom" AND country="GB"

            看上去很完美,不是嗎?這里還有一個例外(可能有多個,但這里指出一個), 這個例外與unique index有關。
            如果數據庫中已經存在了這樣一條記錄: country=GB, name=Vue Cinemas - Cheshire Oaks, address=Ellesmere Port, Coliseum Way, Chesire Oaks Outlet Village, South Wirral CH65 9HD, United Kingdom12321312321, 表(theaters)的unique index是(country, name, address(64)), 那么這個例外就出現了。
            第一條SQL語句執行不會成功, 因為如果插入成功,那么unique index的約束將被破壞--要插入的記錄和已有記錄在unique index語義下是相同的。有意思的是, 第二條SQL同樣找不到數據,因為數據庫中沒有一條記錄它滿足條件(address=....條件得不到滿足)。
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 余江县| 即墨市| 海丰县| 蓬溪县| 班戈县| 建德市| 蒙阴县| 万源市| 浮山县| 仁布县| 沾益县| 勃利县| 英山县| 北京市| 邻水| 正镶白旗| 海淀区| 岳普湖县| 温泉县| 博爱县| 柳河县| 秭归县| 晋州市| 汶上县| 南溪县| 三都| 繁昌县| 水城县| 门头沟区| 乌兰察布市| 绥中县| 鄂尔多斯市| 耒阳市| 宁津县| 彭山县| 南城县| 清流县| 赤城县| 阆中市| 祁门县| 隆林|