我有一个自动递增id
和任意数量的列的表“测试”。
我想在这个表中复制一行,除了id
当然之外,所有列都相同。
有没有办法在不命名所有列的情况下做到这一点?
我认为INSERT... SELECT... ON DUPLICATE KEY
会帮助我,直到我意识到它永远不会生成INSERT ON DUPLICATE
,它只是更新现有的行。
我有一个自动递增id
和任意数量的列的表“测试”。
我想在这个表中复制一行,除了id
当然之外,所有列都相同。
有没有办法在不命名所有列的情况下做到这一点?
我认为INSERT... SELECT... ON DUPLICATE KEY
会帮助我,直到我意识到它永远不会生成INSERT ON DUPLICATE
,它只是更新现有的行。
假设您的表具有以下字段:
( pk_id int not null auto_increment primary key,
col1 int,
col2 varchar(10)
)
然后,要将值从一行复制到具有新键值的另一行,以下查询可能会有所帮助
insert into my_table( col1, col2 ) select col1, col2 from my_table where pk_id=?;
这将为字段生成一个新值,并pk_id
从 和 复制所选行的值。col1
col2
您可以扩展此示例以应用表中的更多字段。
更新:
充分尊重 JohnP 和 Martin 的评论-
我们可以使用临时表先从主表缓冲,然后再用它复制到主表。仅更新临时表中的 pk 引用字段将无济于事,因为它可能已经存在于主表中。相反,我们可以从临时表中删除 pk 字段并将所有其他字段复制到主表中。
参考Tim Ruehsen在参考帖子中的回答:
CREATE TEMPORARY TABLE tmp SELECT * from my_table WHERE ...;
ALTER TABLE tmp drop pk_id; # drop autoincrement field
# UPDATE tmp SET ...; # just needed to change other unique keys
INSERT INTO my_table SELECT 0,tmp.* FROM tmp;
DROP TEMPORARY TABLE tmp;
希望这可以帮助。
这适用于 MySQL 所有版本和 Amazon RDS Aurora:
INSERT INTO my_table SELECT 0,tmp.* FROM tmp;
或者
将索引列设置为 NULL,然后执行 INSERT。
但不是在 MariaDB 中,我测试了版本 10。
编码:
$qrystr = "SELECT * FROM mytablename WHERE id= " . $rowid;
$qryresult = $this->connection->query($qrystr);
$result = $qryresult->fetchAll(PDO::FETCH_ASSOC);
unset($result[0]['id']); //Remove ID from array
$qrystr = " INSERT INTO mytablename";
$qrystr .= " ( " .implode(", ",array_keys($result[0])).") ";
$qrystr .= " VALUES ('".implode("', '",array_values($result[0])). "')";
$result = $this->connection->query($qrystr);
return $result;
当然你应该使用 PDO:bindparam 并检查你的变量是否受到攻击等,但给出了例子
附加信息
如果您在处理NULL
值时遇到问题,您可以使用以下代码,以便imploding
名称和值仅适用于其值不是NULL
.
foreach ($result[0] as $index => $value) {
if ($value === null) unset($result[0][$index]);
}
SET @table = 'the_table';
SELECT GROUP_CONCAT(IF(COLUMN_NAME IN ('id'), 0, CONCAT("\`", COLUMN_NAME, "\`"))) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = @table INTO @columns;
SET @s = CONCAT('INSERT INTO ', @table, ' SELECT ', @columns,' FROM ', @table, ' WHERE id=1');
PREPARE stmt FROM @s;
EXECUTE stmt;
根据有多少列,您可以只命名列,不使用 ID,然后手动添加一个 ID,或者,如果它在您的表中,则添加一个辅助 ID (sid):
insert into PROG(date, level, Percent, sid) select date, level, Percent, 55 from PROG where sid = 31
在这里,如果 sid 31 有多个结果行,所有这些都将被复制到 sid 55 并且您的自动 ID 仍将自动生成。仅用于 ID:
insert into PROG(date, level, Percent, ID) select date, level, Percent, 55 from PROG where ID = 31
其中 55 是表中的下一个可用 ID,ID 31 是您要复制的 ID。
INSERT into table_name (
`product_id`,
`other_products_url_id`,
`brand`,
`title`,
`price`,
`category`,
`sub_category`,
`quantity`,
`buy_now`,
`buy_now_url`,
`is_available`,
`description`,
`image_url`,
`image_type`,
`server_image_url`,
`reviews`,
`hits`,
`rating`,
`seller_name`,
`seller_desc`,
`created_on`,
`modified_on`,
`status`)
SELECT
`product_id`,
`other_products_url_id`,
`brand`,
`title`,
`price`,
`category`,
`sub_category`,
`quantity`,
`buy_now`,
concat(`buy_now_url`,'','#test123456'),
`is_available`,
`description`,
`image_url`,
`image_type`,
`server_image_url`,
`reviews`,
`hits`,
`rating`,
`seller_name`,
`seller_desc`,
`created_on`,
`modified_on`,
`status`
FROM `table_name` WHERE id='YourRowID';