รับคำสั่งแทรกสำหรับแถวที่มีอยู่ใน MySQL


139

ใช้ MySQL ฉันสามารถเรียกใช้แบบสอบถาม:

SHOW CREATE TABLE MyTable;

และมันจะคืนค่าคำสั่งสร้างตารางสำหรับตารางที่ระบุ สิ่งนี้มีประโยชน์หากคุณมีตารางที่สร้างไว้แล้วและต้องการสร้างตารางเดียวกันในฐานข้อมูลอื่น

เป็นไปได้หรือไม่ที่จะได้คำสั่ง insert สำหรับแถวที่มีอยู่แล้วหรือชุดของแถว? บางตารางมีหลายคอลัมน์และมันดีสำหรับฉันที่จะได้รับคำสั่ง insert เพื่อถ่ายโอนแถวไปยังฐานข้อมูลอื่นโดยไม่ต้องเขียนคำสั่ง insert หรือไม่ส่งออกข้อมูลเป็น 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');

คุณใช้เครื่องมือใดในการเชื่อมต่อกับฐานข้อมูล บางโปรแกรมมีเทมเพลตดังกล่าว
GôTô

2
@ kibbee คุณพบวิธีการแก้ปัญหานี้หรือไม่?
Hasina

2
จะรักคำตอบที่แสดงคำสั่ง INSERT จากmysql>พรอมต์ ไม่มีใครทำ
Bob Stein

คุณพบวิธีการแก้ปัญหานี้เพื่อรับคำสั่งแทรกโดยทางโปรแกรมหรือไม่
Vaibhav Jain

คำตอบ:


156

ดูเหมือนจะไม่มีทางได้รับINSERTงบจากคอนโซล MySQL แต่คุณสามารถรับได้โดยใช้mysqldump ตามที่ Rob แนะนำ ระบุ-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" ถ้าคุณต้องการชื่อฟิลด์ / คอลัมน์ด้วยคำสั่ง insert
MeatPopsicle

3
- ธุรกรรม
เดี่ยว

และ--hex-blobถ้าคุณมีคอลัมน์หยด (เช่นก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

เมื่อคุณคัดลอกตารางด้วย SQL ที่สร้างโดยSHOW CREATE TABLE MyTableคุณสามารถทำสิ่งต่อไปนี้เพื่อโหลดข้อมูลลงในตารางใหม่

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
Kibbee

คุณพยายามย้ายชุดย่อยของข้อมูลระหว่างเครื่องหรือไม่ คุณไม่สามารถทาสเครื่องที่สองเพื่อทำมิรเรอร์ข้อมูลจากนั้นย้ายเซ็ตย่อยของคุณระหว่างฐานข้อมูลบน Slave
Rob Prouse

1
มาเถอะเถียงกันว่าฉันมีตารางที่มีเขตเวลา ตอนนี้ด้วยเหตุผลบางอย่างเขตเวลาใหม่จะถูกสร้างขึ้น (อาจมีการชดเชย 15 นาทีหรืออะไรทำนองนั้น) ดังนั้นฉันจึงเพิ่มแถวใหม่ลงในฐานข้อมูลการพัฒนาที่มีข้อมูลทั้งหมดเกี่ยวกับเขตเวลาใหม่และทำการทดสอบที่จำเป็นทั้งหมด เมื่อถึงเวลาที่จะย้ายข้อมูลเขตเวลานั้นไปยังฐานข้อมูลการผลิตฉันต้องสร้างคำสั่งแทรกตั้งแต่เริ่มต้นหรือทำการส่งออก / นำเข้า มันจะเป็นการดีที่จะได้รับการแทรกจากนั้นรวมไว้ในสคริปต์เพื่อทำให้เขตเวลาใหม่สด
Kibbee

1
ฉันไม่มีการแทรกแบบดั้งเดิมเพราะฉันอาจจะแทรกโดยใช้เครื่องมือ GUI หรือฉันอาจต้องเปลี่ยน 3 ครั้งจากค่าเดิมที่ฉันแทรก
Kibbee

1
ฉันบังเอิญต้องการโซลูชันที่ง่ายสำหรับฐานข้อมูลในเครื่องเดียวกันและ google นำมาให้ฉันที่นี่ ดังนั้นผมจึงรู้สึกขอบคุณสำหรับคำตอบนี้แม้ว่าจะออกจากบริบทของคำถามเดิม :)
เจสัน 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
วิธีนี้ค่อนข้างบอบบาง ตัวอย่างเช่นหากหนึ่งในระเบียนของคุณมีชื่อO' Malleyแบบสอบถามที่สร้างขึ้นจะมีข้อผิดพลาดทางไวยากรณ์เนื่องจากการไม่ตรงกันคำพูดเดี่ยว อย่างน้อยคุณควรใช้mysql_real_escape_stringถ้าไปเส้นทางนี้
Eric Seastrand

ยังคงเป็นสิ่งที่ดีฉันจะใช้มันอย่างแน่นอน
user7082181

9

รหัสของ Laptop Lift ใช้งานได้ดี แต่มีบางสิ่งที่ฉันคิดว่าคนอาจชอบ

ตัวจัดการฐานข้อมูลเป็นอาร์กิวเมนต์ไม่ใช่ฮาร์ดโค้ด ใช้ mysql api ใหม่ แทนที่ $ id ด้วย $ ซึ่งเป็นตัวเลือกโดยที่อาร์กิวเมนต์เพื่อความยืดหยุ่น ใช้ real_escape_string ในกรณีที่มีใครเคยลองทำการฉีด sql และเพื่อหลีกเลี่ยงการแตกง่าย ๆ ที่เกี่ยวข้องกับคำพูด ใช้INSERT table (field...) VALUES (value...)...ไวยากรณ์เพื่อให้เขตข้อมูลถูกกำหนดเพียงครั้งเดียวและจากนั้นเพียงรายการออกค่าของแต่ละแถว (implode น่ากลัว) เพราะไนเจลจอห์นสันชี้ให้เห็นว่าฉันเพิ่มการ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).";";
}
?>

ไม่แน่ใจว่าเกี่ยวกับการขาดหายไปINTOในINSERT INTO {$tables}แต่มีการจัดการของ nulls ไม่มีในตาราง
ไนเจลจอห์นสัน

1
@NigelJohnson INTOจะสมบูรณ์ไม่จำเป็น ฉันเพิ่มการจัดการ nulls ลงไป
Chinoto Vokro

6

ฉันใช้โปรแกรมSQLYOGซึ่งฉันสามารถเลือกคิวรีชี้ไปที่ภาพหน้าจอผลลัพธ์และเลือกส่งออกเป็น sql นี่ทำให้ฉันแทรกงบ


เพียงเพื่อหลีกเลี่ยงความสับสนก็ระบุว่ารูปแบบ sql แต่จริง ๆ แล้วส่งออกในรูปแบบ mysql
Kumar Vikramjeet

ขอบคุณ .... +1 เพราะมันใช้งานได้สำหรับฉัน แต่ไม่สามารถรับเฉพาะแถวที่เลือก :( วิธีการของคุณให้แทรกข้อความค้นหาสำหรับแถวทั้งหมดของตาราง #
23251

5

ภายใน MySQL work bench ทำงานต่อไปนี้:

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

, โดยที่ m - จำนวนระเบียนใน your_table


4
บางทีคุณอาจให้คำตอบมากกว่านี้เพียงแค่บล็อกโค้ดที่วางไว้?
Matt Fletcher

ใช่ แต่นี่คือ hardcoded, field_ * เป็นชื่อคงที่ มันทำให้ครึ่งหนึ่งของงานและมันทำให้ไม่ดี
Daniele Cruciani

ทำไม GROUP_CONCAT
sealabr

3

คุณสามารถใช้ Sequel pro เพื่อทำสิ่งนี้มีตัวเลือก 'รับเป็นคำสั่งแทรก' สำหรับผลลัพธ์ที่ได้รับ


3

ใน PHPMyAdmin คุณสามารถ:

  1. คลิกคัดลอกในแถวที่คุณต้องการทราบคำสั่งแทรก SQL:

เลือกคัดลอก

  1. คลิกดูตัวอย่าง SQL:

เลือกดูตัวอย่าง

  1. คุณจะได้คำสั่ง insert ที่สร้างขึ้นมา

คุณสามารถใช้สิ่งนั้นกับหลายแถวพร้อมกันหากคุณเลือกพวกเขาและคลิกคัดลอกจากด้านล่างของตารางจากนั้นดูตัวอย่าง 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 INSERTs" สำหรับ "รูปแบบเอาท์พุท"> คลิกตกลง

ป้อนคำอธิบายรูปภาพที่นี่

คำสั่งแทรกจะอยู่ในคลิปบอร์ดของคุณ


0

ฉันคิดว่าคำตอบของ Laptop Lifts นั้นดีที่สุด ... แต่เนื่องจากไม่มีใครแนะนำวิธีที่ฉันใช้ฉันคิดว่าฉันควรจะพูดสอดฉันใช้ 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.