2010-11-23 6 views
0

MySQL lance toujours une erreur lorsque vous faites quelque chose comme:Comment puis-je 'SELECT INTO' avec des colonnes inconnues?

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

quand un champ et c n'existe pas dans « newtable ». Bien sûr, je comprends que c'est une erreur légitime. Ce que je veux savoir, c'est s'il existe un moyen de construire quelque chose comme une déclaration de cas pour gérer cela. La requête est construite de manière dynamique sur la base d'une table dynamique, donc je n'ai aucun moyen de savoir à l'avance quels champs existent.

Quelles sont vos idées avisées?

Notez que le newtable est défini dynamiquement comme mentionné ci-dessus:

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

Le tableau original ici est mis à jour en fonction des champs de formulaire qui existent sur une forme donnée qui peut être ajouté à, supprimé ou renommé à à tout moment. Le nouveau tableau doit également être conforme à ces changements.

MISE À JOUR: solution de travail suit:

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 % est assez décent, je ne vois pas le problème? – RobertPitt

+0

à peine peut voir en couleur grise, le vert est meilleur – ajreal

Répondre

1

Utilisez Créer table ... Sélectionnez ici est une référence

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

Je ne pense pas que cela fonctionnera pour moi puisque le «newtable» est créé dynamiquement. Les noms de champs de la table newtable proviennent d'un service POST ajax dynamique (variable). –

+0

J'ai mis à jour mon post pour contenir une solution qui fonctionnera. Merci pour votre idée. Je pensais vraiment que votre solution fonctionnerait bien que, dans mon cas, c'était juste une illusion. –

Questions connexes