【问题标题】:Get Insert Statement for existing row in MySQL获取 MySQL 中现有行的插入语句
【发布时间】:2011-04-28 01:24:30
【问题描述】:

使用 MySQL 我可以运行查询:

SHOW CREATE TABLE MyTable;

它会返回指定表的创建表语句。如果您已经创建了一个表,并且想要在另一个数据库上创建同一个表,这将非常有用。

是否可以为已经存在的行或一组行获取插入语句?有些表有很多列,如果能够获得一个插入语句将行传输到另一个数据库,而不必写出插入语句,或者无需将数据导出到 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');

【问题讨论】:

  • 您使用什么工具连接到数据库?一些程序提供这样的模板。
  • @kibbee,你找到解决办法了吗??
  • 希望得到一个显示来自mysql> 提示的 INSERT 语句的答案。目前还没有。
  • 你有没有找到任何解决方案,以编程方式获取插入语句?
  • 试试 MySQL Workbench。通过应用复制粘贴行工作正常。请参阅下面的详细说明。只需单击几下,无需额外的工具或程序。也没有临时文件。

标签: mysql syntax


【解决方案1】:

似乎没有办法从 MySQL 控制台获取 INSERT 语句,但您可以像 Rob 建议的那样使用 mysqldump 获取它们。指定-t 省略表创建。

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

【讨论】:

  • 如果您收到错误 mysqldump: 无法执行 'SELECT @@GTID_MODE': Unknown system variable 'GTID_MODE' (1193) gist.github.com/arun057/5556563,请查看此内容
  • 如果你想要插入语句的字段/列名,你可以添加“--complete-insert”
  • --单笔交易
  • --hex-blob如果你有blob列(例如bit(1)),它会将它写为字符串,否则在执行INSERT时可能会导致Unknown command '\0'错误。
【解决方案2】:

在 MySQL Workbench 中,您可以将任何单表查询的结果导出为 INSERT 语句的列表。只需运行查询,然后:

  1. 点击结果上方Export/Import附近的软盘
  2. 为目标文件命名
  3. 在窗口底部,对于Format,选择SQL INSERT statements
  4. 点击Save
  5. 点击Export

【讨论】:

  • 另外,右侧的图标对于导入您刚刚创建的导出非常方便。非常好的功能。唯一棘手的部分是您只能在选择后从结果集面板访问图标。
  • 非常感谢。正是我想要的
【解决方案3】:

由于您使用 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 实例上运行的数据库来说很好
  • 您是否尝试以编程方式在机器之间移动数据子集?难道你不能从第二台机器镜像数据,然后在从服务器上的数据库之间移动你的子集吗?
  • 让我们,为了争论,我有一个包含时区的表。现在,由于某种原因,创建了一个新时区(可能有 15 分钟的偏移量或类似的东西)。因此,我将新行添加到包含有关新时区的所有信息的开发数据库中,并进行所有必要的测试。当需要将该时区信息移动到生产数据库时,我必须从头开始创建插入语句,或者执行导出/导入。如果能够仅获取插入内容,然后将其包含在脚本中以启用新时区,那就太好了。
  • 我没有原始插入,因为我可能是使用 GUI 工具插入的,或者我可能不得不从插入的原始值更改 3 次。
  • 我碰巧需要一个简单的解决方案来处理同一台机器上的数据库,谷歌把我带到了这里。所以我很感谢这个答案,即使它脱离了原始问题的背景:)
【解决方案4】:

我写了一个 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;
}

【讨论】:

  • 这个解决方案相当脆弱。例如,如果您的一条记录包含名称O' Malley,则生成的查询将由于单引号不匹配而出现语法错误。如果走这条路,你至少应该使用mysql_real_escape_string
  • 还是不错的东西,我一定会用的
【解决方案5】:

Laptop Lift 的代码运行良好,但我认为人们可能会喜欢一些东西。

数据库处理程序是一个参数,不是硬编码的。使用了新的mysql api。将 $id 替换为可选的 $where 参数以提高灵活性。使用 real_escape_string 以防有人尝试过进行 sql 注入并避免涉及引号的简单损坏。使用INSERT table (field...) VALUES (value...)... 语法,以便字段只定义一次,然后列出每一行的值(内爆很棒)。因为奈杰尔约翰逊指出,我添加了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).";";
}
?>

【讨论】:

  • 不确定INSERT INTO {$tables} 上缺少的INTO,但没有处理表中的空值。
  • @NigelJohnson INTO 完全是 optional。我添加了对 null 的处理。
【解决方案6】:

我使用程序SQLYOG 可以进行选择查询,指向 结果并选择导出为sql。这给了我插入语句。

【讨论】:

  • 为了避免混淆,它说的是sql格式,但实际上是以mysql格式导出的。
  • 谢谢.... +1 因为它对我有用。但无法仅获取选定的行。 :( 您的方法为表的所有行提供插入查询。
  • 谢谢,所以我不需要输入那么长的插入
【解决方案7】:

在 MySQL 工作台中执行以下操作:

  1. 点击服务器 > 数据导出

  2. 在“对象选择”选项卡中选择所需的架构。

  3. 接下来,使用架构右侧的列表框选择所需的表。

  4. 选择要导出脚本的文件位置。

  5. 点击完成。

  6. 导航到新创建的文件并复制插入语句。

【讨论】:

  • 这是全表导出,不是特定行导出
【解决方案8】:

如果您想为您的表格获取“插入语句”,您可以尝试以下代码。

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语句:

插入your_tablefield_1field_2...field_n)值(value_11、value_12、...、value_1n);

插入your_tablefield_1field_2...field_n)值(value_21、value_22、...、value_2n);

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

插入your_tablefield_1field_2...field_n)值(value_m1、value_m2、...、value_mn);

,其中 m - your_table 中的记录数

【讨论】:

  • 您能否为您的答案提供更多信息,而不仅仅是粘贴的代码块?
  • 是的,但这是硬编码的,field_* 是静态名称。它完成了一半的工作,但它做得不太好
  • 为什么是 GROUP_CONCAT?
【解决方案9】:

在 PHPMyAdmin 中你可以:

  1. 在你想知道其插入语句SQL的行上点击复制:

  1. 点击预览 SQL:

  1. 您将获得生成它的已创建插入语句

如果您选择它们​​并单击表格底部的复制,然后单击预览 SQl,则可以一次将其应用于多行

【讨论】:

  • 为您的答案添加更多解释和信息
【解决方案10】:

您可以使用 Sequel pro 来执行此操作,对于获得的结果,有一个“get as insert statement”选项

【讨论】:

    【解决方案11】:

    您可以使用以下代码创建 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;
    

    【讨论】:

      【解决方案12】:

      HeidiSQL 用户

      如果您使用 HeidiSQL,您可以选择您希望获取插入语句的行。然后右键单击>导出网格行>为“输出目标”选择“复制到剪贴板”,为“行选择”选择“选择”,这样您就不会导出其他行,为“输出格式”选择“SQL INSERTs”>单击确定。

      插入语句将在您的剪贴板中。

      【讨论】:

        【解决方案13】:

        有一个非常简单实用的解决方案可以创建用于编辑的 INSERT 语句,而无需通过复制和粘贴(剪贴板)导出 SQL:

        • 在 MySQL Workbench 的查询结果窗口中选择行,甚至可能是几行。即使该行确实包含与我想在脚本中插入的数据不同的数据,或者当目标是使用 ? 创建一个准备好的语句时,我也会使用它。占位符。
        • 现在将剪贴板中的复制行粘贴到同一个表中(查询结果列表是工作台中的编辑器)到最后一个空闲行。
        • 按“应用”并打开一个窗口,显示 INSERT 语句 - 不要执行
        • 将 SQL 从窗口复制到剪贴板
        • 取消执行,因此不会更改数据库,而是将 SQL 保留在剪贴板中。
        • 将 SQL 粘贴到您想要的任何位置并根据需要进行编辑,例如插入?占位符

        【讨论】:

          【解决方案14】:

          下面的命令将转储到终端,而 mysqldump 将输出围绕 INSERT 的所有额外内容。这允许从终端复制而不写入文件。如果环境限制写入新文件,这很有用。

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

          使用mysqldump --help我找到了以下选项。

          -q, --quick不缓冲查询,直接转储到标准输出。 (默认开启;使用 --skip-quick 禁用。)

          -t, --no-create-info 不要写表创建信息。

          -c, --complete-insert 使用完整的插入语句。

          --compact 减少冗长的输出(对调试很有用)。禁用 结构 cmets 和页眉/页脚结构。启用 选项 --skip-add-drop-table --skip-add-locks --skip-cmets --skip-disable-keys --skip-set-charset。

          【讨论】:

            【解决方案15】:

            使用 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;
            

            【讨论】:

              【解决方案16】:

              如果您使用 phpMyAdmin(在 5.x 版上测试):

              点击您想要插入语句的行旁边的“编辑”按钮,然后在操作按钮旁边的底部选择“显示插入查询”并按“开始”。

              【讨论】:

                【解决方案17】:

                我认为笔记本电脑升降机提供的答案是最好的......但由于没有人建议我使用的方法,我想我应该插话。我大部分时间都使用 phpMyAdmin 来设置和管理我的数据库。在其中,您可以简单地将复选标记放在您想要的行旁边,然后在底部单击“导出”并选择 SQL。它将为您选择的任何记录提供 INSERT 语句。希望这会有所帮助。

                【讨论】:

                  【解决方案18】:

                  你可以试试这个

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

                  要使用它,只需调用:

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

                  【讨论】:

                    【解决方案19】:

                    根据您的 cmets,您的目标是将数据库更改从开发环境迁移到生产环境。

                    做到这一点的最佳方法是将数据库更改保留在源代码中,然后在源代码控制系统(例如 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));
                        }
                    }
                    

                    然后您可以创建一个迁移脚本,它将根据您的规范更新任何环境。

                    【讨论】:

                      猜你喜欢
                      • 2016-05-11
                      • 1970-01-01
                      • 1970-01-01
                      • 2018-09-25
                      • 2020-11-07
                      • 2016-04-15
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多