2010-11-23 6 views
0

MySQL은 항상 다음과 같은 일을 할 때 오류가 발생합니다 :알 수없는 열이있는 'SELECT INTO'는 어떻게합니까?

INSERT INTO `newtable` 
(`a`, `b`, `c`, `d`) 
SELECT 
`a`, `b`, `c` , `d` FROM `oldtable` 

필드 a와 c가 'newtable'에 존재하지 않을 때. 물론 이것은 합법적 인 오류라고 생각합니다. 제가 알고 싶은 것은, 이것을 처리하기위한 사례 진술과 같은 것을 만들 수있는 방법이 있는지입니다. 쿼리는 동적 테이블을 기반으로 동적으로 작성되므로 어떤 필드가 존재하는지 알 수있는 방법이 없습니다.

잘 아는 아이디어는 무엇입니까?

newtable은 위에서 언급 한대로 동적으로 정의됩니다.

public function updateTableSchema($table, $fields) 
{ 
    // Drop the temporary table if exists 
    $sql = " 
     DROP TABLE IF EXISTS `temp_{$table}` 
    "; 
    if (!$this->db()->query($sql)) return FALSE; 

    // Make a backup of the original table and select the old values into it 
    $sql = " 
     CREATE TABLE `temp_{$table}` 
     SELECT * FROM `$table` 
    "; 
    if (!$this->db()->query($sql)) return FALSE; 

    // Drop the old table 
    if (!$this->db()->query("DROP TABLE `$table`")) return FALSE; 

    // Recreate the table with the new fields 
    $sql = " 
     CREATE TABLE IF NOT EXISTS `$table` 
     (\n"; 

     $sql .= "`id` int(11) NOT NULL AUTO_INCREMENT,\n"; 
     foreach ($fields as $field) 
     { 
      $sql .= html_entity_decode("`$field` varchar(255) NOT NULL,\n"); 
     } 
     $sql .= "PRIMARY KEY (`id`)\n"; 

    $sql .= " 
     ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 
    "; 
    if (!$this->db()->query($sql)) return FALSE; 

    CREATE TABLE new_tbl SELECT * FROM orig_tbl; 

    // Insert the temporary records into the new table 
    $sql = "INSERT INTO `$table` ("; 
    foreach ($fields as $field) 
    { 
     $sql .= html_entity_decode("`$field`, "); 
    } 
    $sql = rtrim($sql, ', ') . ') SELECT '; 
    foreach ($fields as $field) 
    { 
     $sql .= html_entity_decode("`$field`, "); 
    } 
    $sql = rtrim($sql, ', ') . " FROM `temp_{$table}`"; 
    print $sql; 
    if (!$this->db()->query($sql)) return FALSE; 

    // Drop the temporary table 
    $sql = "DROP TABLE `temp_{$table}`"; 
    return $this->db()->query($sql); 
} 

여기에 원래 테이블은 지정된 양식에 존재하는 양식 필드를 기반으로 업데이트되며 여기에 추가하거나 삭제하거나 이름을 변경할 수 있습니다 언제든지. 새 테이블은 이러한 변경 사항과 일치해야합니다.

업데이트 : 다음과 같이 작업하십시오.

public function updateTableSchema($table, $fields) 
{ 
    // Drop the temporary table if exists 
    $sql = " 
     DROP TABLE IF EXISTS `temp_{$table}` 
    "; 
    if (!$this->db()->query($sql)) return FALSE; 

    // Make a backup of the original table and select the old values into it 
    $sql = " 
     CREATE TABLE `temp_{$table}` 
     SELECT * FROM `$table` 
    "; 
    if (!$this->db()->query($sql)) return FALSE; 

    // Drop the old table 
    if (!$this->db()->query("DROP TABLE `$table`")) return FALSE; 

    // Recreate the table with the new fields 
    $sql = " 
     CREATE TABLE IF NOT EXISTS `$table` 
     (\n"; 

     $sql .= "`id` int(11) NOT NULL AUTO_INCREMENT,\n"; 
     foreach ($fields as $field) 
     { 
      $sql .= html_entity_decode("`$field` varchar(255) NOT NULL,\n"); 
     } 
     $sql .= "PRIMARY KEY (`id`)\n"; 

    $sql .= " 
     ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 
    "; 
    if (!$this->db()->query($sql)) return FALSE; 

    // Insert the temporary records into the new table 
    $sql = "INSERT INTO `$table` ("; 
    foreach ($fields as $field) 
    { 
     $sql .= html_entity_decode("`$field`, "); 
    } 
    $sql = rtrim($sql, ', ') . ') SELECT '; 
    foreach ($fields as $field) 
    { 
     $sql .= html_entity_decode("`$field`, "); 
    } 
    $sql = rtrim($sql, ', ') . " FROM `temp_{$table}`"; 

    try 
    { 
     $this->db()->query($sql); 
    } 
    catch (error $e) 
    { 
     if (preg_match('/Unknown column/', $e->getMessage())) 
     { 
      $new_field = utility::getStringBetween($e->getMessage(), "'", "'"); 
      if (!$new_field) return FALSE; 

      $this->db()->query("TRUNCATE TABLE `$table`"); 
      $key = array_search($new_field, $fields); 
      $key--; 

      // Check if adding after 
      if ($key > 0) 
      { 
       $sql = " 
        ALTER TABLE `temp_{$table}` 
        ADD `$new_field` VARCHAR(255) NOT NULL AFTER `{$fields[$key]}` 
       "; 
       if (!$this->db()->query($sql)) return FALSE; 
      } 
      // Check if adding before 
      else 
      { 
       $sql = " 
        ALTER TABLE `temp_{$table}` 
        ADD `$new_field` VARCHAR(255) NOT NULL FIRST 
       "; 
       if (!$this->db()->query($sql)) return FALSE; 
      } 

      // Insert the temporary records into the new table 
      $sql = "INSERT INTO `$table` ("; 
      foreach ($fields as $field) 
      { 
       $sql .= html_entity_decode("`$field`, "); 
      } 
      $sql = rtrim($sql, ', ') . ') SELECT '; 
      foreach ($fields as $field) 
      { 
       $sql .= html_entity_decode("`$field`, "); 
      } 
      $sql = rtrim($sql, ', ') . " FROM `temp_{$table}`"; 
      if (!$this->db()->query($sql)) return FALSE; 
     } 
    } 

    // Drop the temporary table 
    $sql = "DROP TABLE `temp_{$table}`"; 
    return $this->db()->query($sql); 
} 
+1

69입니다 %는 꽤 괜찮습니다. 문제가 보이지 않습니까? – RobertPitt

+0

겨우 회색으로 볼 수 있습니다. 녹색이 더 좋습니다. – ajreal

답변

1

사용이 ... 테이블 만들기 여기 선택은 일부 참조

http://dev.mysql.com/doc/refman/5.0/en/create-table-select.html

http://dev.mysql.com/doc/refman/5.0/en/create-table.html

CREATE TABLE new_tbl SELECT * FROM orig_tbl; 
+0

'newtable'이 동적으로 만들어 졌으므로이 기능이 작동하지 않을 것이라고 생각합니다. newtable의 필드 이름은 동적 (변수) ajax POST 서비스에서 가져옵니다. –

+0

해결할 수있는 솔루션이 포함되도록 게시물을 업데이트했습니다. 당신의 아이디어에 감사드립니다. 나는 정말로 당신의 솔루션이 효과가있을 것이라고 생각했지만, 제 경우에는 단지 환상 일뿐입니다. –

관련 문제