2010-11-23 3 views
0

MySQL всегда выдает ошибку, когда делает что-то вроде:Как я могу «SELECT INTO» с неизвестными столбцами?

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

, когда поле а и с не существует в «Новая_таблица». Конечно, я понимаю, что это законная ошибка. Я хочу знать, есть ли способ построить что-то вроде case-case для обработки этого. Запрос динамически строится на основе динамической таблицы, поэтому мне неизвестно, какие поля существуют.

Какие у вас сообразительные идеи?

Обратите внимание, что Новая_таблица определяется динамически, как указано выше:

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); 
} 

Исходная таблица здесь обновляется на основе полей формы, которые существуют на заданной формы, которые могут быть добавлены, удалены из или переименованный в в любой момент. Новая таблица также должна соответствовать этим изменениям.

UPDATE: Рабочий раствор следующим образом:

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 2010-11-23 18:32:07

+0

едва может видеть в сером цвете, зеленый лучше – ajreal 2010-11-23 18:44:03

ответ