ChatGPT解决这个技术问题 Extra ChatGPT

Get Insert Statement for existing row in MySQL

Using MySQL I can run the query:

SHOW CREATE TABLE MyTable;

And it will return the create table statement for the specificed table. This is useful if you have a table already created, and want to create the same table on another database.

Is it possible to get the insert statement for an already existing row, or set of rows? Some tables have many columns, and it would be nice for me to be able to get an insert statement to transfer rows over to another database without having to write out the insert statement, or without exporting the data to CSV and then importing the same data into the other database.

Just to clarify, what I want is something that would work as follows:

SHOW INSERT Select * FROM MyTable WHERE ID = 10;

And have the following returned for me:

INSERT INTO MyTable(ID,Col1,Col2,Col3) VALUES (10,'hello world','some value','2010-10-20');
What tool do you use to connect to the DB? Some programs provide such templates.
@kibbee, Have you found any solution for this??
Would love an answer that showed the INSERT statements from the mysql> prompt. None so far do.
have you found any solution for this, to get the insert statement programmatically ?
Try MySQL Workbench. Copy Paste of Rows works fine via Apply. See my detailled instructions below. A few clicks and no extra tools or procedures required. Also no temporary files.

T
Tyler Crompton

There doesn't seem to be a way to get the INSERT statements from the MySQL console, but you can get them using mysqldump like Rob suggested. Specify -t to omit table creation.

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

See this if you get the error mysqldump: Couldn't execute 'SELECT @@GTID_MODE': Unknown system variable 'GTID_MODE' (1193) gist.github.com/arun057/5556563
And you can add " --complete-insert" if you want the field/column names with the insert statement
--single-transaction
and --hex-blob if you have blob columns (for example a bit(1)), it would write it as string otherwise, which could result in Unknown command '\0' error when executing the INSERT.
--compact to eliminate all the cruft and just get the insert statement by itself.
Z
Zoltán

In MySQL Workbench you can export the results of any single-table query as a list of INSERT statements. Just run the query, and then:

https://i.stack.imgur.com/76Rmz.png

click on the floppy disk near Export/Import above the results give the target file a name at the bottom of the window, for Format select SQL INSERT statements click Save click Export


Also, the icon to the right is very handy for importing the export you just created. Very nice feature. The only tricky part is that you can only access the icons from the results set panel after a select.
Many thanks for this. Exactly what I was looking for
R
Rob Prouse

Since you copied the table with the SQL produced by SHOW CREATE TABLE MyTable, you could just do the following to load the data into the new table.

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

If you really want the INSERT statements, then the only way that I know of is to use mysqldump http://dev.mysql.com/doc/refman/5.1/en/mysqldump.htm. You can give it options to just dump data for a specific table and even limit rows.


The databases in question exist on physically different machines, on different networks, so this method wouldn't work for me, but works fine for databases running on the same instance of MySQL
Are you trying to programatically move subsets of data between machines? Couldn't you slave the second machine to mirror data, then move your subsets between databases on the slave?
Let's, for argument's sake say I have a table that contains Time Zones. Now, for some reason a new time zone is created (perhaps with a 15 minute offset or something like that). So I add the new row to the development database that contains all the information about the new timezone and do all the necessary testing. When it comes time to move that timezone information to the production database I have to create an insert statement from scratch, or do a export/import. It would be nice to be able to just get the insert, and then include it in the scripts to bring the new timezone live.
I don't have the original insert because I may have inserted it using a GUI tool, or I may have had to change it 3 times from the original values I inserted.
I happened to be needing a simple solution for databases on the same machine and google brought me here. So I am thankful for this answer, even if it was out of context of the original question :)
C
Chris Adams

I wrote a php function that will do this. I needed to make an insert statement in case a record needs to be replaced after deletion for a history table:

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

This solution is quite fragile. For example, if one of your records contains the name O' Malley, the generated queries will have syntax errors due to mismatching single-quotes. You should at least use mysql_real_escape_string if going this route.
still nice stuff, I'll use it for sure
C
Chinoto Vokro

Laptop Lift's code works fine, but there were a few things I figured people may like.

Database handler is an argument, not hardcoded. Used the new mysql api. Replaced $id with an optional $where argument for flexibility. Used real_escape_string in case anyone has ever tried to do sql injection and to avoid simple breakages involving quotes. Used the INSERT table (field...) VALUES (value...)... syntax so that the fields are defined only once and then just list off the values of each row (implode is awesome). Because Nigel Johnson pointed it out, I added NULL handling.

I used $array[$key] because I was worried it might somehow change, but unless something is horribly wrong, it shouldn't anyway.

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

Not sure about the missing INTO on INSERT INTO {$tables} but there is no handling of nulls in the table.
@NigelJohnson INTO is completely optional. I added handling of nulls to it.
M
Mosab B. Nazli

In PHPMyAdmin you can:

click copy on the row you want to know its insert statements SQL:

https://i.stack.imgur.com/BlrgT.png

click Preview SQL:

https://i.stack.imgur.com/HeUjS.png

you will get the created insert statement that generates it

You can apply that on many rows at once if you select them and click copy from the bottom of the table and then Preview SQl


Add more explanations and information to your answer
Sorry. Just notice this answer came before Teodor Hirs's answer. This was increbily easy to follow and doesn't need any more explanation or information. I admire all the attempts to answer this important question, but I think this should be the accepted answer. A common situation is that you don't have root access, SSH access using a console, remote access, or other basic tools to make it possible to follow the other suggestions. However, phpMyAdmin is probably the most ubiquitous tool available and this is an incredibly simple solution.
A
Ashwin A

https://i.stack.imgur.com/h6nNE.png


Just to avoid confusion, it says sql format but it actually exports in mysql format.
Thanks.... +1 as it worked for me. But could not get for only selected rows. :( Your method giving insert query for all rows of the table.
Thank's so i don't need to type insert with that long
G
Gabe Gates

The below command will dump into the terminal without all the extra stuff mysqldump will output surrounding the INSERT. This allows copying from the terminal without it writing to a file. This is useful if the environment restricts writing new files.

mysqldump -u MyUserName -pMyPassword MyDatabase MyTable --where="ID = 10" --compact --no-create-info --complete-insert --quick

Using mysqldump --help I found the following options.

-q, --quick Don't buffer query, dump directly to stdout. (Defaults to on; use --skip-quick to disable.) -t, --no-create-info Don't write table creation info. -c, --complete-insert Use complete insert statements. --compact Give less verbose output (useful for debugging). Disables structure comments and header/footer constructs. Enables options --skip-add-drop-table --skip-add-locks --skip-comments --skip-disable-keys --skip-set-charset.


K
Kevin Bowersox

Within MySQL work bench perform the following:

Click Server > Data Export In the Object Selection Tab select the desired schema. Next, select the desired tables using the list box to the right of the schema. Select a file location to export the script. Click Finish. Navigate to the newly created file and copy the insert statements.


this is a full table export , not a specific rows exporting
s
slava157

If you want get "insert statement" for your table you can try the following code.

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

As a result, you will have insers statement:

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

, where m - number of records in your_table


Could you perhaps provide a little more to your answer than just a pasted code block?
yep, but this is hardcoded, field_* are static names. It makes half of the work, and it makes it not so well
why GROUP_CONCAT?
f
flash

you can use Sequel pro to do this, there is an option to 'get as insert statement' for the results obtained


F
FINARX

There is a quite easy and useful solution for creating an INSERT Statement for editing without the need to export SQL with just Copy & Paste (Clipboard):

Select the row in a query result window of MySQL Workbench, probably even several rows. I use this even if the row does contain different data than I want to insert in my script or when the goal is to create a prepared statement with ? placeholders.

Paste the copied row which is in your clipboard now into the same table (query results list is an editor in workbench) into the last free row.

Press "Apply" and a windows opens showing you the INSERT statement - DO NOT EXECUTE

Copy the SQL from the window to your clipboard

CANCEL the execution, thus not changing the database but keeping the SQL in your clipboard.

Paste the SQL wherever you want and edit it as you like, like e.g. inserting ? placeholders


s
snyman

You can create a SP with the code below - it supports NULLS as well.

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;

f
fall

For HeidiSQL users:

If you use HeidiSQL, you can select the row(s) you wish to get insert statement. Then right click > Export grid rows > select "Copy to clipboard" for "Output target", "Selection" for "Row Selection" so you don't export other rows, "SQL INSERTs" for "Output format" > Click OK.

https://i.stack.imgur.com/VT7ZF.png

The insert statement will be inside you clipboard.


T
Teodor Hirs

In case you use phpMyAdmin (Tested on version 5.x):

Click on "Edit" button next to the row for which you would like to have an insert statement, then on the bottom next to the action buttons just select "Show insert query" and press "Go".


I admire all the attempts to answer this important question, but I think this should be the accepted answer. A common situation is that you don't have root access, SSH access using a console, remote access, or other basic tools to make it possible to follow the other suggestions. However, phpMyAdmin is probably the most ubiquitous tool available and this is an incredibly simple solution.
J
Josh Bernfeld

With PDO you can do it this way.

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

t
techtheatre

I think that the answer provided by Laptop Lifts is best...but since nobody suggested the approach that I use, i figured i should chime in. I use phpMyAdmin to set up and manage my databases most of the time. In it, you can simply put checkmarks next to the rows you want, and at the bottom click "Export" and chose SQL. It will give you INSERT statements for whichever records you selected. Hope this helps.


M
Mohamad Hamouday

You can try this

function get_insert_query($pdo, $table, $where_sth)
{
    $sql = "";
    $row_data = $pdo->query("SELECT * FROM `{$table}` WHERE $where_sth")->fetch();
    if($row_data){
        $sql = "INSERT INTO `$table` (";

        foreach($row_data as $col_name => $value){
            $sql .= "`".$col_name."`, ";
        }
        $sql = rtrim($sql, ", ");

        $sql .= ") VALUES (";

        foreach($row_data as $col_name => $value){
            if (is_string($value)){
                $value = $pdo->quote($value);
            } else if ($value === null){
                $value = 'NULL';
            }

            $sql .= $value .", ";
        }
        $sql = rtrim($sql, ", ");
        $sql .= ");";
    }

    return $sql;
}

To use it, just call:

$pdo = new PDO( "connection string goes here" );
$sql = get_insert_query($pdo, 'texts', "text_id = 959");
echo $sql;

t
toni-gar-20

Update for get insert statement for current registers at PhpMyAdmin:

Select the table from you DB to get registers from "Export" tab at the top menú as the image below

https://i.stack.imgur.com/kDUg8.png

Custom export Move down to "Data creation options"

https://i.stack.imgur.com/xf0vf.png

Once there, select "Insert" function at your preferred syntax


R
RangaM

Its very simple. All you have to do is write an Insert statement in a static block and run it as a script as a whole block.

E.g. If you want to get Insert statements from a table (say ENGINEER_DETAILS) for selected rows, then you have to run this block -

spool 
set sqlformat insert
select * from ENGINEER_DETAILS where engineer_name like '%John%';
spool off;

The output of this block will be Insert statements.


Spool seems to be Oracle specific and isn't available in MySQL.
A
Ali Gangji

Based on your comments, your goal is to migrate database changes from a development environment to a production environment.

The best way to do this is to keep your database changes in your source code and consequently track them in your source control system such as git or svn.

you can get up and running quickly with something like this: https://github.com/davejkiger/mysql-php-migrations

as a very basic custom solution in PHP, you can use a function like this:

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

then you can create a migration script which will update any environment to your specifications.