Ottieni l'istruzione Insert per la riga esistente in MySQL


139

Utilizzando MySQL posso eseguire la query:

SHOW CREATE TABLE MyTable;

E restituirà l'istruzione create table per la tabella specifica. Ciò è utile se si dispone già di una tabella e si desidera creare la stessa tabella su un altro database.

È possibile ottenere l'istruzione insert per una riga o un set di righe già esistenti? Alcune tabelle hanno molte colonne e sarebbe bello poter ottenere un'istruzione insert per trasferire le righe su un altro database senza dover scrivere l'istruzione insert o senza esportare i dati in CSV e quindi importare gli stessi dati nell'altro database.

Giusto per chiarire, quello che voglio è qualcosa che funzioni come segue:

SHOW INSERT Select * FROM MyTable WHERE ID = 10;

E mi viene restituito quanto segue:

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

Quale strumento usi per connetterti al DB? Alcuni programmi forniscono tali modelli.
GôTô,

2
@kibbee, hai trovato qualche soluzione per questo ??
Hasina,

2
Mi piacerebbe una risposta che mostrasse le istruzioni INSERT dal mysql>prompt. Nessuno finora.
Bob Stein,

hai trovato una soluzione per questo, per ottenere l'istruzione insert a livello di codice?
Vaibhav Jain,

Risposte:


156

Non sembra esserci un modo per ottenere le INSERTdichiarazioni dalla console MySQL, ma puoi ottenerle usando mysqldump come suggerito da Rob. Specifica -tdi omettere la creazione della tabella.

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

Vedi questo se viene visualizzato l'errore mysqldump: Impossibile eseguire 'SELECT @@ GTID_MODE': Variabile di sistema sconosciuta 'GTID_MODE' (1193) gist.github.com/arun057/5556563
Daniel Schaffer

10
E puoi aggiungere "--complete-insert" se vuoi i nomi di campo / colonna con l'istruzione insert
MeatPopsicle

3
--single-transazione
FelikZ

e --hex-blobse si dispone di colonne BLOB (ad esempio a bit(1)), la scriverebbe come stringa altrimenti, il che potrebbe causare Unknown command '\0'errori durante l'esecuzione di INSERT.
moffeltje,

79

In MySQL Workbench puoi esportare i risultati di qualsiasi query a tabella singola come un elenco di INSERTistruzioni. Basta eseguire la query e quindi:

Istantanea del pulsante di esportazione

  1. fai clic sul dischetto vicino Export/Importsopra i risultati
  2. assegnare un nome al file di destinazione
  3. nella parte inferiore della finestra, per FormatselezionareSQL INSERT statements
  4. clic Save
  5. clic Export

2
Inoltre, l'icona a destra è molto utile per importare l'esportazione appena creata. Caratteristica molto bella. L'unica parte difficile è che puoi accedere alle icone dal pannello del set di risultati solo dopo una selezione.
Half_Duplex,

13

Dal momento che hai copiato la tabella con l'SQL prodotto da SHOW CREATE TABLE MyTable , potresti semplicemente fare quanto segue per caricare i dati nella nuova tabella.

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

Se vuoi davvero le istruzioni INSERT, l'unico modo che conosco è usare mysqldump http://dev.mysql.com/doc/refman/5.1/en/mysqldump.htm . Puoi dargli le opzioni solo per scaricare i dati per una tabella specifica e persino limitare le righe.


I database in questione esistono su macchine fisicamente diverse, su reti diverse, quindi questo metodo non funzionerebbe per me, ma funziona bene per i database in esecuzione sulla stessa istanza di MySQL
Kibbee,

Stai cercando di spostare programmaticamente sottoinsiemi di dati tra macchine? Non è possibile asservire il secondo computer per il mirroring dei dati, quindi spostare i sottoinsiemi tra i database sullo slave?
Rob Prouse,

1
Diciamo che, per l'argomento, ho una tabella che contiene fusi orari. Ora, per qualche motivo viene creato un nuovo fuso orario (forse con un offset di 15 minuti o qualcosa del genere). Quindi aggiungo la nuova riga al database di sviluppo che contiene tutte le informazioni sul nuovo fuso orario e faccio tutti i test necessari. Quando arriva il momento di spostare le informazioni sul fuso orario nel database di produzione, devo creare un'istruzione insert da zero o eseguire un'esportazione / importazione. Sarebbe bello poter semplicemente inserire l'inserto e quindi includerlo negli script per rendere attivo il nuovo fuso orario.
Kibbee,

1
Non ho l'inserto originale perché potrei averlo inserito usando uno strumento GUI, o potrei aver dovuto cambiarlo 3 volte dai valori originali che ho inserito.
Kibbee,

1
Mi è capitato di aver bisogno di una soluzione semplice per i database sullo stesso computer e Google mi ha portato qui. Quindi sono grato per questa risposta, anche se era fuori dal contesto della domanda originale :)
Jason McCarrell,

10

Ho scritto una funzione php che lo farà. Avevo bisogno di fare un'istruzione insert nel caso in cui un record debba essere sostituito dopo l'eliminazione per una tabella della cronologia:

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
Questa soluzione è abbastanza fragile. Ad esempio, se uno dei record contiene il nome O' Malley, le query generate avranno errori di sintassi a causa della mancata corrispondenza tra virgolette singole. Dovresti usare almeno mysql_real_escape_stringse segui questa strada.
Eric Seastrand,

roba ancora carina, lo userò di sicuro
user7082181

9

Il codice di Laptop Lift funziona bene, ma ci sono alcune cose che immagino possano piacere alla gente.

Il gestore del database è un argomento, non codificato. Usato il nuovo mysql api. Sostituito $ id con un argomento facoltativo $ where per la flessibilità. Utilizzato real_escape_string nel caso in cui qualcuno abbia mai provato a fare l'iniezione sql ed evitare semplici rotture che comportano virgolette. Ho usato la INSERT table (field...) VALUES (value...)...sintassi in modo che i campi siano definiti solo una volta e poi elenchino i valori di ogni riga (l'impllode è fantastico). Perché Nigel Johnson lo ha sottolineato, ho aggiuntoNULL gestione.

Ho usato $array[$key]perché ero preoccupato che potesse in qualche modo cambiare, ma a meno che qualcosa non sia terribilmente sbagliato, non dovrebbe comunque.

<?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).";";
}
?>

Non sono sicuro di ciò che manca INTO, INSERT INTO {$tables}ma non c'è gestione dei null nella tabella.
Nigel Johnson,

1
@NigelJohnson INTOè completamente opzionale . Ho aggiunto la gestione dei null ad esso.
Chinoto Vokro,

6

Uso il programma SQLYOG dove posso fare una query di selezione, puntare ai immagine dello schermorisultati e scegliere esportazione come sql. Questo mi dà le istruzioni insert.


Solo per evitare confusione, dice il formato sql ma in realtà esporta in formato mysql.
Kumar Vikramjeet,

Grazie .... +1 come ha funzionato per me. Ma non è stato possibile ottenere solo le righe selezionate. :( Il tuo metodo che fornisce la query di inserimento per tutte le righe della tabella.
Mukit09

5

All'interno del banco di lavoro MySQL, eseguire le seguenti operazioni:

  1. Fare clic su Server> Esportazione dati

  2. Nella scheda Selezione oggetto selezionare lo schema desiderato.

  3. Quindi, selezionare le tabelle desiderate utilizzando la casella di riepilogo a destra dello schema.

  4. Seleziona un percorso per esportare lo script.

  5. Fai clic su Fine.

  6. Passare al file appena creato e copiare le istruzioni di inserimento.


si tratta dell'esportazione di una tabella completa, non di un'esportazione di righe specifiche
Yehia,

4

Se vuoi ottenere "insert statement" per la tua tabella puoi provare il seguente codice.

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`;

Di conseguenza, avrai la dichiarazione degli inser:

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

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

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

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

, dove m - numero di record in your_table


4
Potresti forse fornire un po 'di più alla tua risposta di un semplice blocco di codice incollato?
Matt Fletcher,

sì, ma questo è hardcoded, field_ * sono nomi statici. Fa metà del lavoro, e non lo fa così bene
Daniele Cruciani,

perché GROUP_CONCAT?
sealabr,

3

puoi usare Sequel pro per fare questo, c'è un'opzione per 'get as insert insert' per i risultati ottenuti


3

In PHPMyAdmin puoi:

  1. fare clic su copia sulla riga che si desidera conoscere le istruzioni di inserimento SQL:

Seleziona copia

  1. fare clic su Anteprima SQL:

Seleziona Anteprima

  1. otterrai l'istruzione insert creata che la genera

Puoi applicarlo su più righe contemporaneamente se le selezioni e fai clic su Copia dalla parte inferiore della tabella e quindi su Anteprima SQl


Aggiungi ulteriori spiegazioni e informazioni alla tua risposta
Ramin eghbalian,

2

Per gli utenti HeidiSQL :

Se si utilizza HeidiSQL, è possibile selezionare le righe che si desidera ottenere l'istruzione insert. Quindi fai clic con il pulsante destro del mouse> Esporta righe griglia> seleziona "Copia negli Appunti" per "Destinazione output", "Selezione" per "Selezione riga" in modo da non esportare altre righe, "INSERTI SQL" per "Formato di output"> Fai clic su OK.

inserisci qui la descrizione dell'immagine

L'istruzione insert sarà negli appunti.


1

Con DOP puoi farlo in questo modo.

$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

Puoi creare un SP con il codice seguente: supporta anche 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

Penso che la risposta fornita da Laptop Lifts sia la migliore ... ma dal momento che nessuno mi ha suggerito l'approccio che uso, ho pensato che avrei dovuto intervenire. Uso phpMyAdmin per impostare e gestire i miei database per la maggior parte del tempo. In esso, puoi semplicemente mettere i segni di spunta accanto alle righe che desideri, e in basso fai clic su "Esporta" e scegli SQL. Ti fornirà le istruzioni INSERT per qualsiasi record selezionato. Spero che questo ti aiuti.


-1

Sulla base dei tuoi commenti, il tuo obiettivo è migrare le modifiche al database da un ambiente di sviluppo a un ambiente di produzione.

Il modo migliore per farlo è mantenere le modifiche al database nel codice sorgente e, di conseguenza, monitorarle nel sistema di controllo del codice sorgente come git o svn.

puoi metterti rapidamente in funzione con qualcosa del genere: https://github.com/davejkiger/mysql-php-migrations

come soluzione personalizzata di base in PHP, puoi usare una funzione come questa:

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

quindi è possibile creare uno script di migrazione che aggiornerà qualsiasi ambiente alle proprie specifiche.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.