用同一个表的克隆值替换字段值

时间:2015-11-05 17:39:24

标签: mysql stored-procedures replace

我有一个包含以下字段的表格。

Account,DeviceID,timestamp,odometer

前三个字段是主键 某些deviceID在不同的帐户中克隆。 现在这些克隆已经损坏了里程表。

Account,DeviceID,timestamp,odometer
 1        A         001      145
 1        A         002      147
 1        A         003      148
 2        A         001      145
 2        A         002      NULL
 2        A         003      0

帐户2中的设备A是帐户1中设​​备A的克隆。

那么,如何将帐户1和设备A的里程表值克隆到帐户2中设备A的相同时间戳?

我需要创建一个商店程序,我可以通过三个参数,OriginalAccount,CloneAccount,DeviceID,来逐个修复所有克隆。

修改

如果我有以下数据

+---------+-----------+-----------+----------+
| account | device_id | timestamp | odometer |
+---------+-----------+-----------+----------+
|       1 | A         |       001 |      145 |
|       1 | A         |       002 |      147 |
|       1 | A         |       003 |      148 |
|       2 | A         |       001 |      145 |
|       2 | A         |       002 |     NULL |
|       2 | A         |       003 |        0 |

调用存储过程后,表必须如下所示

+---------+-----------+-----------+----------+
| account | device_id | timestamp | odometer |
+---------+-----------+-----------+----------+
|       1 | A         |       001 |      145 |
|       1 | A         |       002 |      147 |
|       1 | A         |       003 |      148 |
|       2 | A         |       001 |      145 |
|       2 | A         |       002 |      147 |
|       2 | A         |       003 |      148 |

1 个答案:

答案 0 :(得分:1)

模式

create table thing7
(   account int not null,
    device_id varchar(10) not null,
    `timestamp` int(3) zerofill not null,   -- not a great column name btw (it is a keyword, not a reserved word)
    odometer int null,
    primary key(account,device_id,timestamp)
);
insert thing7(account,device_id,timestamp,odometer) values
(1,'A',1,145),
(1,'A',2,147),
(1,'A',3,148),
(2,'A',1,145),
(2,'A',2,NULL),
(2,'A',3,0);

在开始时查看数据:

select * from thing7;
+---------+-----------+-----------+----------+
| account | device_id | timestamp | odometer |
+---------+-----------+-----------+----------+
|       1 | A         |       001 |      145 |
|       1 | A         |       002 |      147 |
|       1 | A         |       003 |      148 |
|       2 | A         |       001 |      145 |
|       2 | A         |       002 |     NULL |
|       2 | A         |       003 |        0 |
+---------+-----------+-----------+----------+

存储过程

drop procedure if exists cloneIt;
DELIMITER $$
create procedure cloneIt
(   srcAcct int, -- the data of the source to be copied
    destAcct int,   -- the target to receive it
    device varchar(10)
)
BEGIN
    -- clean out any old junk in case src does not match dest
    -- this is due to edge conditions where dest has more rows than src, and you said you want a clone
    delete from thing7 where account=destAcct and device_id=device;

    -- now clone it
    insert thing7(account,device_id,`timestamp`,odometer)
    select destAcct,device_id,`timestamp`,odometer
    from thing7
    where account=srcAcct and device_id=device;
END
$$
DELIMITER ;

分隔符设置错误会浪费时间。拥有它们或研究它们的用途。

克隆1到7:

call cloneIt(1,7,'A');

测试一个边缘条件:dest有比src更多的信息

insert thing7(account,device_id,timestamp,odometer) values
(14,'A',1,145),
(14,'A',2,147),
(14,'A',3,148),
(14,'A',4,199);

14现在有4行

call cloneIt(1,14,'A');

查看结果:

select * from thing7;
+---------+-----------+-----------+----------+
| account | device_id | timestamp | odometer |
+---------+-----------+-----------+----------+
|       1 | A         |       001 |      145 |
|       1 | A         |       002 |      147 |
|       1 | A         |       003 |      148 |
|       2 | A         |       001 |      145 |
|       2 | A         |       002 |     NULL |
|       2 | A         |       003 |        0 |
|       7 | A         |       001 |      145 |
|       7 | A         |       002 |      147 |
|       7 | A         |       003 |      148 |
|      14 | A         |       001 |      145 |
|      14 | A         |       002 |      147 |
|      14 | A         |       003 |      148 |
+---------+-----------+-----------+----------+

cloneIt有效。它创建了精确的克隆