【问题标题】:Duplicate a database row by it's ID按 ID 复制数据库行
【发布时间】:2012-01-08 08:08:51
【问题描述】:

我们是否可以简单地根据 ID 复制数据库中的条目,而不必提及要复制的行的所有字段名称。

我有一排看起来像

id name last city state whatever
1  joe  doe  xyz  NY    yyy

我想复制一份。 id 是自动增量。最简单的方法是什么。

【问题讨论】:

标签: php mysql


【解决方案1】:

我也喜欢用不同的方式。如果 MySQL db 用户帐户没有 DROP 权限的安全措施:

SELECT `col1`, `col2`, `col3` FROM `table`

将结果放入一个数组中,然后将该数组插入到数据库中。如果您想修改要包含的名称,也有帮助 - 在其后复制。

INSERT INTO `table` (`col1`, `col2`, `col3`) VALUES (?,?,?)

占位符可以是可变数组访问器($name -- 其中 $name = $array[0])。这可能是多个步骤,但在复制的情况下,您最有可能复制单行。如果有多行,则过程可能会比其他答案慢。

【讨论】:

    【解决方案2】:

    根据您对@Adam Wenger 的回答的评论,我会读取一个查询中的所有字段,然后构建一个新查询,跳过id 字段。

    类似:

    SELECT * FROM table_name WHERE id=some_id
    

    php:

    $sql = "INSERT INTO table_name SET ";
    $first = true;
    foreach ($row as $key => $value)
    {
      if ($key != 'id')
      {
         if ($first) 
         {
            $first = false;
         }
         else
         {
           $sql .= ", ";
         }
         $sql .= '`' . $key . "`='" . $value . "'";
      }
    }
    // run query
    

    顺便说一句,我会在 PDO 中为这两个查询生成一个准备好的语句,这样我就不必担心转义数据了。

    【讨论】:

      【解决方案3】:

      如果您不想列出所有字段,则必须使用 information_schema 和prepared statements。

      这是一个例子

      set @str = (select concat('insert into ', table_name,' (', group_concat(column_name),')',' select ',group_concat(column_name),' from ', table_name, ' where id = 1') from 
      information_schema.columns
      where table_schema = 'your_db' and table_name = 'your_table'
      and column_key <> 'PRI');
      prepare stmt from @str;
      execute stmt;
      deallocate prepare stmt;
      

      您甚至可以在存储过程中通过以下方式对其进行转换:向其传递三个参数(id、表名和数据库名):

      delimiter //
      drop procedure if exists copy_record //
      create procedure copy_record(in my_id int, in my_db varchar(50), in my_table varchar(50) )
      begin
      set @str = (select concat('insert into ', table_name,' (', group_concat(column_name),')',' select ',group_concat(column_name),' from ', table_name, ' where id = ',my_id) from 
      information_schema.columns
      where table_schema = my_db and table_name = my_table
      and column_key <> 'PRI');
      prepare stmt from @str;
      execute stmt;
      deallocate prepare stmt;
      end; //
      delimiter ;
      
      call copy_record(1,'db_name','table_name');
      

      【讨论】:

        【解决方案4】:

        显示您正在做的最清晰的方法是明确命名列。这可确保您获得所需的功能,并且对于在您之后必须修改此代码的任何人都一目了然。

        INSERT INTO yourTable(name, last, city, state, whatever)
        SELECT name, last, city, state, whatever
        FROM yourTable
        WHERE id = 1
        

        如果你真的想因为未知字段而动态插入记录,你需要使用动态 SQL 和来自INFORMATION_SCHEMA.COLUMNS 的数据,并在循环或类似结构中自己构建字段名称。

        【讨论】:

        • 谢谢,但在我的问题中,我问是否有办法做到这一点而不必提及所有字段名称
        • 我不认为你可以在不调用列的情况下做到这一点,因为 ID 是一个自动增量,你不能只是这样做并插入 yourTable() 因为你不希望自动增量填充相同的值。
        • @Pinkie,你需要为击键付费吗?
        • 客户可以从管理区域动态添加/删除字段。我希望重复函数也是动态的,而不必提及任何字段名称。
        • @Pinkie 我已经更新了我的答案,提到了动态 SQL 和 INFORMATION_SCHEMA 视图来解决真正的动态请求
        猜你喜欢
        • 2022-11-01
        • 2011-06-09
        • 2013-04-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-11
        • 2012-07-14
        • 2023-03-19
        相关资源
        最近更新 更多