MySQLの既存の行の挿入ステートメントを取得する


139

MySQLを使用して、クエリを実行できます。

SHOW CREATE TABLE MyTable;

そして、指定されたテーブルのcreate tableステートメントを返します。これは、すでにテーブルが作成されていて、同じテーブルを別のデータベースに作成したい場合に便利です。

既存の行または行のセットの挿入ステートメントを取得することは可能ですか?一部のテーブルには多くの列があり、挿入ステートメントを書き出すことなく、またはデータをCSVにエクスポートしてから同じデータをインポートすることなく、挿入ステートメントを取得して行を別のデータベースに転送できると便利です。他のデータベースに。

明確にするために、私が欲しいのは次のように機能するものです:

SHOW INSERT Select * FROM MyTable WHERE ID = 10;

そして、私のために次のものが返されます:

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

DBに接続するにはどのツールを使用しますか?一部のプログラムはそのようなテンプレートを提供します。
後藤

2
@kibbee、これの解決策を見つけましたか?
Hasina 2013年

2
mysql>プロンプトからのINSERTステートメントを示した答えが気に入りました。今のところ何もしません。
ボブスタイン

プログラムでinsertステートメントを取得するために、これに対する解決策を見つけましたか?
Vaibhav Jain 2017

回答:


155

INSERTMySQLコンソールからステートメントを取得する方法はないようですが、Robが提案したようにmysqldumpを使用してステートメントを取得できます。-tテーブルの作成を省略することを指定します。

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

エラーmysqldumpが発生した場合は、これを参照してください: 'SELECT @@ GTID_MODE'を実行できませんでした:不明なシステム変数 'GTID_MODE'(1193) gist.github.com/arun057/5556563
Daniel Schaffer

10
また、挿入ステートメントでフィールド/列名が必要な場合は、「--complete-insert」を追加できます
MeatPopsicle

3
--single-transaction
FelikZ 2017

また--hex-blob、BLOB列(例:a bit(1))がある場合、それを文字列として書き込むためUnknown command '\0'、INSERTの実行時にエラーが発生する可能性があります。
moffeltje

79

MySQL Workbenchでは、単一テーブルクエリの結果をINSERTステートメントのリストとしてエクスポートできます。クエリを実行し、次に:

エクスポートボタンのスナップショット

  1. Export/Import結果の上にあるフロッピーディスクをクリックします
  2. ターゲットファイルに名前を付けます
  3. ウィンドウの下部にある Format選択用SQL INSERT statements
  4. クリック Save
  5. クリック Export

2
また、右側のアイコンは、作成したエクスポートをインポートするのに非常に便利です。とても素敵な機能。唯一のトリッキーな部分は、選択後に結果セットパネルからのみアイコンにアクセスできることです。
Half_Duplex

13

SHOW CREATE TABLE MyTableによって生成されたSQLを使用してテーブルをコピーしたので、次のようにしてデータを新しいテーブルにロードできます。

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

本当にINSERTステートメントが必要な場合、私が知っている唯一の方法はmysqldump http://dev.mysql.com/doc/refman/5.1/en/mysqldump.htmを使用することです。特定のテーブルのデータをダンプするだけでなく、行を制限することもできます。


問題のデータベースは物理的に異なるマシン、異なるネットワーク上に存在するため、この方法は私には機能しませんが、MySQLの同じインスタンスで実行されているデータベースでは
正常に機能し

マシン間でプログラムによってデータのサブセットを移動しようとしていますか?2番目のマシンをスレーブ化してデータをミラーリングし、スレーブ上のデータベース間でサブセットを移動できませんか?
Rob Prouse、

1
議論のために、タイムゾーンを含むテーブルがあるとしましょう。ここで、何らかの理由で新しいタイムゾーンが作成されます(おそらく15分のオフセットなどで)。そこで、新しいタイムゾーンに関するすべての情報を含む新しい行を開発データベースに追加し、必要なすべてのテストを行います。そのタイムゾーン情報を本番データベースに移動するときになると、ゼロからinsertステートメントを作成するか、エクスポート/インポートを実行する必要があります。挿入を取得し、それをスクリプトに含めて新しいタイムゾーンをライブにできると便利です。
Kibbee

1
GUIツールを使用して挿入したか、挿入した元の値から3回変更しなければならなかった可能性があるため、元の挿入はありません。
Kibbee、

1
私はたまたま同じマシン上のデータベースのためのシンプルなソリューションを必要としており、グーグルは私をここに連れてきました。ですから、元の質問の文脈から外れていたとしても、私はこの回答に感謝します:)
Jason McCarrell

10

これを行うphp関数を作成しました。履歴テーブルの削除後にレコードを置き換える必要がある場合に備えて、挿入ステートメントを作成する必要がありました。

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
このソリューションは非常に壊れやすいです。たとえば、レコードの1つに名前が含まれているO' Malley場合、生成されたクエリには一重引用符の不一致が原因で構文エラーが発生します。mysql_real_escape_stringこのルートを使用する場合は、少なくとも使用する必要があります。
エリックイーストランド2017

それでもいいもの、私はそれを確実に使用します
user7082181

9

Laptop Liftのコードは問題なく動作しますが、人々が気に入ると思われることがいくつかありました。

データベースハンドラーは引数であり、ハードコードされていません。新しいmysql apiを使用しました。柔軟性を高めるために、$ idをオプションの$ where引数に置き換えました。誰かがSQLインジェクションを行い、引用符を含む単純な破損を回避しようとした場合に備えて、real_escape_stringを使用しました。INSERT table (field...) VALUES (value...)...構文を使用して、フィールドが1回だけ定義され、各行の値をリストするだけになりました(分解は素晴らしいです)。Nigel Johnsonが指摘したので、NULL処理。

$array[$key]どういうわけか変わるのではないかと心配して使ってみましたが、ひどく間違っていない限り、とにかく変わらないはずです。

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

行方不明わからないINTOINSERT INTO {$tables}はなくヌルのない取扱いがテーブルにありません。
Nigel Johnson、

1
@NigelJohnson INTOは完全にオプションです。nullの処理を追加しました。
Chinoto Vokro 2014年

6

SQLYOGプログラムを使用して、選択クエリを作成しスクリーンショット、結果をポイントして、SQLとしてエクスポートを選択します。これは私に挿入ステートメントを与えます。


混乱を避けるために、それはsql形式を示していますが、実際にはmysql形式でエクスポートされます。
Kumar Vikramjeet

おかげで.... +1になりました。しかし、選択された行だけを取得できませんでした。:(テーブルのすべての行に対して挿入クエリを与えるあなたのメソッド
Mukit09

5

MySQLワークベンチ内で、以下を実行します。

  1. [サーバー]> [データのエクスポート]をクリックします

  2. [オブジェクトの選択]タブで、目的のスキーマを選択します。

  3. 次に、スキーマの右側にあるリストボックスを使用して、目的のテーブルを選択します。

  4. スクリプトをエクスポートするファイルの場所を選択します。

  5. 完了をクリックします。

  6. 新しく作成されたファイルに移動し、挿入ステートメントをコピーします。


これはテーブル全体のエクスポートであり、特定の行のエクスポートではありません
Yehia

4

テーブルの「挿入ステートメント」を取得したい場合は、次のコードを試すことができます。

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

その結果、insersステートメントがあります。

INSERT INTO your_tablefield_1field_2...field_n)VALUES(value_11、value_12、...、value_1n)。

INSERT INTO your_tablefield_1field_2...field_n)VALUES(value_21、value_22、...、value_2n)。

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

INSERT INTO your_tablefield_1field_2...field_n)VALUES(value_m1、value_m2、...、value_mn)。

、ここでm-your_table内のレコード数


4
おそらく、貼り付けたコードブロックだけではなく、もう少し多くの回答を提供できますか?
マットフレッチャー

うん、しかしこれはハードコードされており、field_ *は静的な名前です。それは仕事の半分を作り、そしてそれはそれほどうまくいきません
ダニエレ・クルチャニ

なぜGROUP_CONCATなのか?
シーラブル

3

Sequel proを使用してこれを行うことができます。取得した結果に対して「挿入ステートメントとして取得」するオプションがあります


3

PHPMyAdminでは、次のことができます。

  1. 挿入ステートメントSQLを知りたい行で[コピー]をクリックします。

コピーを選択

  1. [SQLプレビュー]をクリックします。

プレビューを選択

  1. あなたはそれを生成する作成された挿入ステートメントを取得します

それらを選択し、テーブルの下部にある[コピー]をクリックしてから[SQLのプレビュー]をクリックすると、一度に多くの行にそれを適用できます。


回答に説明と情報を追加します
Ramin eghbalian

1

PDOを使用すると、この方法でそれを行うことができます。

$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

以下のコードでSPを作成できます。これは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;

1

HeidiSQLユーザーの場合

HeidiSQLを使用する場合、挿入ステートメントを取得する行を選択できます。次に、右クリック> [グリッド行をエクスポート]> [出力ターゲット]で[クリップボードにコピー]、[行選択]で[選択]を選択し、他の行をエクスポートしないようにします。[出力形式]で[SQL INSERT]> [OK]をクリックします。

ここに画像の説明を入力してください

insertステートメントはクリップボードの中にあります。


0

私はラップトップリフトによって提供される答えが最良であると思います...しかし、私が使用するアプローチを誰も提案しなかったので、私は干渉するべきだと考えました。phpMyAdminを使用して、ほとんどの場合データベースをセットアップおよび管理します。その中で、必要な行の横にチェックマークを付けるだけで、下部にある[エクスポート]をクリックしてSQLを選択できます。選択したレコードのINSERTステートメントが表示されます。お役に立てれば。


-1

コメントに基づいて、目標はデータベースの変更を開発環境から本番環境に移行することです。

これを行う最善の方法は、データベースの変更をソースコードに保存し、その結果、gitやsvnなどのソース管理システムで変更を追跡することです。

次のようなものですばやく起動して実行できます:https : //github.com/davejkiger/mysql-php-migrations

PHPの非常に基本的なカスタムソリューションとして、次のような関数を使用できます。

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

次に、環境に合わせて仕様を更新する移行スクリプトを作成できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.