Obtenir une instruction d'insertion pour une ligne existante dans MySQL


139

En utilisant MySQL, je peux exécuter la requête:

SHOW CREATE TABLE MyTable;

Et il renverra l'instruction create table pour la table spécifique. Ceci est utile si vous avez déjà créé une table et que vous souhaitez créer la même table sur une autre base de données.

Est-il possible d'obtenir l'instruction d'insertion pour une ligne déjà existante ou un ensemble de lignes? Certaines tables ont de nombreuses colonnes, et ce serait bien pour moi de pouvoir obtenir une instruction d'insertion pour transférer des lignes vers une autre base de données sans avoir à écrire l'instruction d'insertion, ou sans exporter les données au format CSV, puis importer les mêmes données dans l'autre base de données.

Juste pour clarifier, ce que je veux, c'est quelque chose qui fonctionnerait comme suit:

SHOW INSERT Select * FROM MyTable WHERE ID = 10;

Et faites-moi revenir ce qui suit:

INSERT INTO MyTable(ID,Col1,Col2,Col3) VALUES (10,'hello world','some value','2010-10-20');

Quel outil utilisez-vous pour vous connecter à la base de données? Certains programmes fournissent de tels modèles.
GôTô

2
@kibbee, avez-vous trouvé une solution pour cela ??
Hasina

2
J'adorerais une réponse qui montrait les instructions INSERT de l' mysql>invite. Aucun pour l'instant.
Bob Stein

avez-vous trouvé une solution pour cela, pour obtenir l'instruction d'insertion par programme?
Vaibhav Jain

Réponses:


156

Il ne semble pas y avoir de moyen d'obtenir les INSERTinstructions de la console MySQL, mais vous pouvez les obtenir en utilisant mysqldump comme Rob l'a suggéré. Spécifiez -tpour omettre la création de table.

mysqldump -t -u MyUserName -pMyPassword MyDatabase MyTable --where="ID = 10"

Voyez ceci si vous obtenez l'erreur mysqldump: Impossible d'exécuter 'SELECT @@ GTID_MODE': Variable système inconnue 'GTID_MODE' (1193) gist.github.com/arun057/5556563
Daniel Schaffer

10
Et vous pouvez ajouter "--complete-insert" si vous voulez les noms de champ / colonne avec l'instruction d'insertion
MeatPopsicle

3
--single-transaction
FelikZ

et --hex-blobsi vous avez des colonnes blob (par exemple a bit(1)), il l'écrirait sous forme de chaîne sinon, ce qui pourrait entraîner une Unknown command '\0'erreur lors de l'exécution de INSERT.
moffeltje

79

Dans MySQL Workbench, vous pouvez exporter les résultats de toute requête à table unique sous forme de liste d' INSERTinstructions. Exécutez simplement la requête, puis:

Instantané du bouton d'exportation

  1. cliquez sur la disquette Export/Importau-dessus des résultats
  2. donner un nom au fichier cible
  3. en bas de la fenêtre, pour FormatsélectionnerSQL INSERT statements
  4. Cliquez sur Save
  5. Cliquez sur Export

2
De plus, l'icône à droite est très pratique pour importer l'export que vous venez de créer. Très belle fonctionnalité. La seule partie délicate est que vous ne pouvez accéder aux icônes du panneau de résultats qu'après une sélection.
Half_Duplex

13

Puisque vous avez copié la table avec le SQL produit par SHOW CREATE TABLE MyTable , vous pouvez simplement faire ce qui suit pour charger les données dans la nouvelle table.

INSERT INTO dest_db.dest_table SELECT * FROM source_db.source_table;

Si vous voulez vraiment les instructions INSERT, alors le seul moyen que je connaisse est d'utiliser mysqldump http://dev.mysql.com/doc/refman/5.1/en/mysqldump.htm . Vous pouvez lui donner des options pour simplement vider les données d'une table spécifique et même limiter les lignes.


Les bases de données en question existent sur des machines physiquement différentes, sur des réseaux différents, donc cette méthode ne fonctionnerait pas pour moi, mais fonctionne bien pour les bases de données s'exécutant sur la même instance de MySQL
Kibbee

Essayez-vous de déplacer par programme des sous-ensembles de données entre des machines? Ne pouviez-vous pas asservir la deuxième machine pour mettre en miroir les données, puis déplacer vos sous-ensembles entre les bases de données sur l'esclave?
Rob Prouse

1
Disons, par souci d'argumentation, que j'ai une table qui contient les fuseaux horaires. Maintenant, pour une raison quelconque, un nouveau fuseau horaire est créé (peut-être avec un décalage de 15 minutes ou quelque chose comme ça). J'ajoute donc la nouvelle ligne à la base de données de développement qui contient toutes les informations sur le nouveau fuseau horaire et fais tous les tests nécessaires. Quand vient le temps de déplacer ces informations de fuseau horaire vers la base de données de production, je dois créer une instruction d'insertion à partir de zéro, ou faire une exportation / importation. Ce serait bien de pouvoir simplement obtenir l'insertion, puis de l'inclure dans les scripts pour mettre en ligne le nouveau fuseau horaire.
Kibbee

1
Je n'ai pas l'insert d'origine car je l'ai peut-être inséré à l'aide d'un outil GUI, ou j'ai peut-être dû le changer 3 fois par rapport aux valeurs d'origine que j'ai insérées.
Kibbee

1
J'avais besoin d'une solution simple pour les bases de données sur la même machine et Google m'a amené ici. Je suis donc reconnaissant pour cette réponse, même si elle était hors du contexte de la question initiale :)
Jason McCarrell

10

J'ai écrit une fonction php qui fera cela. J'avais besoin de faire une déclaration d'insertion au cas où un enregistrement doit être remplacé après la suppression d'une table d'historique:

function makeRecoverySQL($table, $id)
{
    // get the record          
    $selectSQL = "SELECT * FROM `" . $table . "` WHERE `id` = " . $id . ';';

    $result = mysql_query($selectSQL, $YourDbHandle);
    $row = mysql_fetch_assoc($result); 

    $insertSQL = "INSERT INTO `" . $table . "` SET ";
    foreach ($row as $field => $value) {
        $insertSQL .= " `" . $field . "` = '" . $value . "', ";
    }
    $insertSQL = trim($insertSQL, ", ");

    return $insertSQL;
}

3
Cette solution est assez fragile. Par exemple, si l'un de vos enregistrements contient le nom O' Malley, les requêtes générées présenteront des erreurs de syntaxe dues à des guillemets simples incompatibles. Vous devriez au moins utiliser mysql_real_escape_stringsi vous empruntez cette voie.
Eric Seastrand

toujours des trucs sympas, je vais l'utiliser à coup sûr
user7082181

9

Le code de Laptop Lift fonctionne bien, mais il y avait quelques choses que je pensais que les gens pourraient aimer.

Le gestionnaire de base de données est un argument, non codé en dur. Utilisé la nouvelle api mysql. Remplacement de $ id par un argument optionnel $ where pour la flexibilité. Utilisé real_escape_string au cas où quelqu'un aurait déjà essayé de faire une injection SQL et pour éviter de simples ruptures impliquant des guillemets. Utilisé la INSERT table (field...) VALUES (value...)...syntaxe pour que les champs ne soient définis qu'une seule fois, puis listent simplement les valeurs de chaque ligne (imploser est génial). Parce que Nigel Johnson l'a souligné, j'ai ajouté la NULLmanipulation.

J'avais l'habitude $array[$key]parce que j'avais peur que cela puisse changer d'une manière ou d'une autre, mais à moins que quelque chose ne cloche horriblement, cela ne devrait pas de toute façon.

<?php
function show_inserts($mysqli,$table, $where=null) {
    $sql="SELECT * FROM `{$table}`".(is_null($where) ? "" : " WHERE ".$where).";";
    $result=$mysqli->query($sql);

    $fields=array();
    foreach ($result->fetch_fields() as $key=>$value) {
        $fields[$key]="`{$value->name}`";
    }

    $values=array();
    while ($row=$result->fetch_row()) {
        $temp=array();
        foreach ($row as $key=>$value) {
            $temp[$key]=($value===null ? 'NULL' : "'".$mysqli->real_escape_string($value)."'");
        }
        $values[]="(".implode(",",$temp).")";
    }
    $num=$result->num_rows;
    return "INSERT `{$table}` (".implode(",",$fields).") VALUES \n".implode(",\n",$values).";";
}
?>

Je ne sais pas sur les disparus INTOsur , INSERT INTO {$tables}mais il n'y a pas de manipulation dans le tableau des valeurs nulles.
Nigel Johnson

1
@NigelJohnson INTOest complètement facultatif . J'y ai ajouté la gestion des nulls.
Chinoto Vokro

6

J'utilise le programme SQLYOG où je peux faire une requête de sélection, pointer sur capture d'écranles résultats et choisir l'exportation en sql. Cela me donne les instructions d'insertion.


Juste pour éviter toute confusion, il est indiqué au format sql mais il exporte en fait au format mysql.
Kumar Vikramjeet

Merci .... +1 car cela a fonctionné pour moi. Mais n'a pas pu obtenir pour les lignes sélectionnées uniquement. :( Votre méthode donnant une requête d'insertion pour toutes les lignes de la table.
Mukit09

5

Dans le banc de travail MySQL, procédez comme suit:

  1. Cliquez sur Serveur> Exportation de données

  2. Dans l'onglet Sélection d'objet, sélectionnez le schéma souhaité.

  3. Ensuite, sélectionnez les tables souhaitées à l'aide de la zone de liste à droite du schéma.

  4. Sélectionnez un emplacement de fichier pour exporter le script.

  5. Cliquez sur Terminer.

  6. Accédez au fichier nouvellement créé et copiez les instructions d'insertion.


il s'agit d'une exportation de table complète, pas d'une exportation de lignes spécifiques
Yehia

4

Si vous souhaitez obtenir une "instruction d'insertion" pour votre table, vous pouvez essayer le code suivant.

SELECT 
    CONCAT(
        GROUP_CONCAT(
            CONCAT(
                'INSERT INTO `your_table` (`field_1`, `field_2`, `...`, `field_n`) VALUES ("',
                `field_1`,
                '", "',
                `field_2`,
                '", "',
                `...`,
                '", "',
                `field_n`,
                '")'
            ) SEPARATOR ';\n'
        ), ';'
    ) as `QUERY`
FROM `your_table`;

En conséquence, vous aurez une déclaration d'insers:

INSERT INTO your_table( field_1, field_2, ..., field_n) VALUES (value_11, value_12, ..., value_1n);

INSERT INTO your_table( field_1, field_2, ..., field_n) VALUES (value_21, value_22, ..., value_2n);

/ ................................................. .... /

INSERT INTO your_table( field_1, field_2, ..., field_n) VALUES (value_m1, value_m2, ..., value_mn);

, où m - nombre d'enregistrements dans votre_table


4
Pourriez-vous peut-être fournir un peu plus à votre réponse qu'un simple bloc de code collé?
Matt Fletcher

oui, mais c'est codé en dur, field_ * sont des noms statiques. Cela fait la moitié du travail et cela ne le rend pas si bien
Daniele Cruciani

pourquoi GROUP_CONCAT?
sealabr

3

vous pouvez utiliser Sequel pro pour ce faire, il existe une option pour 'obtenir une instruction d'insertion' pour les résultats obtenus


3

Dans PHPMyAdmin, vous pouvez:

  1. cliquez sur copier sur la ligne dont vous voulez connaître ses instructions d'insertion SQL:

Sélectionnez une copie

  1. cliquez sur Aperçu SQL:

Sélectionnez Aperçu

  1. vous obtiendrez l'instruction d'insertion créée qui la génère

Vous pouvez l'appliquer sur plusieurs lignes à la fois si vous les sélectionnez et cliquez sur copier à partir du bas du tableau, puis sur Aperçu SQl


Ajouter plus d'explications et d'informations à votre réponse
Ramin eghbalian

2

Pour les utilisateurs HeidiSQL :

Si vous utilisez HeidiSQL, vous pouvez sélectionner la (les) ligne (s) que vous souhaitez obtenir une instruction d'insertion. Puis faites un clic droit> Exporter les lignes de la grille> sélectionnez "Copier dans le presse-papier" pour "Cible de sortie", "Sélection" pour "Sélection de ligne" afin de ne pas exporter d'autres lignes, "INSERT SQL" pour "Format de sortie"> Cliquez sur OK.

entrez la description de l'image ici

L'instruction d'insertion sera à l'intérieur de votre presse-papiers.


1

Avec PDO, vous pouvez le faire de cette façon.

$stmt = DB::getDB()->query("SELECT * FROM sometable", array());

$array = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $fields = array_keys($array[0]);

    $statement = "INSERT INTO user_profiles_copy (".implode(",",$fields).") VALUES ";
    $statement_values = null;

    foreach ($array as $key => $post) {
        if(isset($statement_values)) {
            $statement_values .= ", \n";
        }

        $values = array_values($post);
        foreach($values as $index => $value) {
            $quoted = str_replace("'","\'",str_replace('"','\"', $value));
            $values[$index] = (!isset($value) ? 'NULL' : "'" . $quoted."'") ;
        }

        $statement_values .= "(".implode(',',$values).")";


    }
    $statement .= $statement_values . ";";

    echo $statement;

1

Vous pouvez créer un SP avec le code ci-dessous - il prend également en charge NULLS.

select 'my_table_name' into @tableName;

/*find column names*/
select GROUP_CONCAT(column_name SEPARATOR ', ') from information_schema.COLUMNS
where table_schema =DATABASE()
and table_name = @tableName
group by table_name
into @columns
;

/*wrap with IFNULL*/
select replace(@columns,',',',IFNULL(') into @selectColumns;
select replace(@selectColumns,',IFNULL(',',\'~NULL~\'),IFNULL(') into @selectColumns;

select concat('IFNULL(',@selectColumns,',\'~NULL~\')') into @selectColumns;

/*RETRIEVE COLUMN DATA FIELDS BY PK*/
SELECT
  CONCAT(
    'SELECT CONCAT_WS(','''\'\',\'\''',' ,
    @selectColumns,
    ') AS all_columns FROM ',@tableName, ' where id = 5 into @values;'
    )
INTO @sql;

PREPARE stmt FROM @sql;
EXECUTE stmt;

/*Create Insert Statement*/
select CONCAT('insert into ',@tableName,' (' , @columns ,') values (\'',@values,'\')') into @prepared;

/*UNWRAP NULLS*/
select replace(@prepared,'\'~NULL~\'','NULL') as statement;

0

Je pense que la réponse fournie par Laptop Lifts est la meilleure ... mais puisque personne n'a suggéré l'approche que j'utilise, j'ai pensé que je devrais intervenir. J'utilise phpMyAdmin pour configurer et gérer mes bases de données la plupart du temps. Dans celui-ci, vous pouvez simplement mettre des coches à côté des lignes que vous voulez, et en bas, cliquez sur "Exporter" et choisissez SQL. Il vous donnera des instructions INSERT pour les enregistrements que vous avez sélectionnés. J'espère que cela t'aides.


-1

Sur la base de vos commentaires, votre objectif est de migrer les modifications de base de données d'un environnement de développement vers un environnement de production.

La meilleure façon de faire est de conserver les modifications de votre base de données dans votre code source et par conséquent de les suivre dans votre système de contrôle de source tel que git ou svn.

vous pouvez être opérationnel rapidement avec quelque chose comme ceci: https://github.com/davejkiger/mysql-php-migrations

en tant que solution personnalisée très basique en PHP, vous pouvez utiliser une fonction comme celle-ci:

function store_once($table, $unique_fields, $other_fields=array()) {
    $where = "";
    $values = array();
    foreach ($unique_fields as $k => $v) {
        if (!empty($where)) $where .= " && ";
        $where .= "$k=?";
        $values[] = $v;
    }
    $records = query("SELECT * FROM $table WHERE $where", $values);
    if (false == $records) {
        store($table, array_merge($unique_fields, $other_fields));
    }
}

vous pouvez ensuite créer un script de migration qui mettra à jour n'importe quel environnement selon vos spécifications.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.