如何使用ID将两个表从一个表更新到另一个表?

问题描述

我正在编写一个Node JS脚本,我想用它来更新远程数据库中的2个表。到目前为止,该脚本执行以下操作:

  • 它连接到远程数据库,选择给定时间以来的新值。
  • 它连接到本地数据库,将新的/编辑的行插入或更新到表A。
  • 使用表A中的ID作为主键,将新行更新或插入到第二个表中。 我已经完成了任务1和2。

到目前为止,我的代码

let MysqL = require('MysqL');

let con = MysqL.createConnection({ //Server A
    host: "192.168.1.10",user: "user1",password: "pswd1",database: "a_database"
});

let con2 = MysqL.createConnection({ //Server B
    host: "192.168.1.11",user: "user2",password: "pswd2",database: "b_database"
});

let sqlSelectDatabaseA = "SELECT uid,name,email,city,street,number FROM users \n" +
    "WHERE uid IN (SELECT disTINCT u.uid FROM logs l INNER JOIN users u ON l.id = u.uid ORDER BY uid;";

let sqlSelectId = "SELECT max(id) AS ID FROM addresses";

let sqlInsertUsers = "INSERT INTO users (username,mobile,client_number,contactAddress) VALUES ? ON DUPLICATE KEY UPDATE \n" +
"username=VALUES(username),email=VALUES(email),mobile=VALUES(mobile),city=VALUES(city),street=VALUES(street);"; //I've solved the insert/update in this sql command
let sqlInsertAddresses = "INSERT INTO addresses (country,number) VALUES ?"; //Here I would need update too

con.connect(async function(err) {
    if (err) throw err;
    con.query(sqlSelectDatabaseA,function (err,result) {
        if (err) throw err;
        con2.connect(function(err) {
            if (err) throw err;
            con2.query(sqlSelectId,result2) {
                if (err) throw err;
                let addressId = result2[0].ID;
                let values1 = [];
                let values2 = [];
                for (let i = 0; i < result.length; i++) {
                    addressId++;
                    values1[i] = [result[i].city,result[i].street,result[i].number];
                    values2[i] = [result[i].name,result[i].email,result[i].city,result[i].street + ' ' + result[i].number,result[i].uid,++addressId];
                }
                con2.query(sqlInsertAddresses,[values1],result3) {
                    if (err)
                        throw err;
                    console.log("Number of records inserted/updated in addresses table : " + result3.affectedRows); //Now I only insert the addresses,don't check them if they exist,this would be the task,to achieve a check if it exists or not,if exists,update it,if not,insert it
                    con2.query(sqlInsertUsers,[values2],result4) {
                        if (err) throw err;
                        console.log("Number of records inserted/updated in users table: " + result4.affectedRows);
                        con.end();
                        con2.end();
                    });
                });

            });

        });
    });
});

我想找到一种解决方案,用于将users.contactAddress的值用作地址表上的PRIMARY KEY。如果存在具有给定主键的记录,则仅更新值,否则不更新,则插入新记录。

如果可能,没有新的sql命令。但是,如果没有其他方法,那也可以。

示例:

  • 在日志表中出现了新的一行,看起来像| logId | userId |
  • 脚本使用该行的userId,连接到数据库A,并从users表中获取新值
  • 使用数据库A中的值,脚本将插入或更新数据库B中的users表
  • 取决于是否进行了更新或插入,它会在地址表中添加一行,或者更新地址表中的值(其中id(主键)等于更新用户记录的contactAddress字段)

Database structure

CREATE TABLE IF NOT EXISTS usersA (
  `uid` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(255) NOT NULL,`email` varchar(255) NOT NULL,`mobile` varchar(255) NOT NULL,`city` varchar(255) NOT NULL,`street` varchar(255) NOT NULL,`number` bigint(20) NOT NULL,PRIMARY KEY (`uid`)
);
CREATE TABLE IF NOT EXISTS logsA (
  `logId` int(11) NOT NULL AUTO_INCREMENT,`userId` varchar(255) NOT NULL,PRIMARY KEY (`logId`)
);
CREATE TABLE IF NOT EXISTS addressesB (
  `id` int(11) NOT NULL AUTO_INCREMENT,`buildingNumber` varchar(255) NOT NULL,PRIMARY KEY (`id`)
);
CREATE TABLE IF NOT EXISTS usersB (
  `id` int(11) NOT NULL AUTO_INCREMENT,`klient_number` bigint(20) NOT NULL,`contactAddress` bigint(20) NOT NULL,PRIMARY KEY (`id`),UNIQUE KEY `klient_number` (`klient_number`)
);
INSERT INTO usersA (username,number) VALUES("John Smith","john.smith@gmail.com","0000","city","street",15);
INSERT INTO usersA (username,number) VALUES("Kate Smith","kate.smith@gmail.com","city_updated","street1",11);
INSERT INTO usersA (username,number) VALUES("Will Smith","will.smith@gmail.com","city2","street2",6);
INSERT INTO usersB (username,klient_number,contactAddress) VALUES("John Smith","street 15",1,1);
INSERT INTO usersB (username,contactAddress) VALUES("Kate Smith","city 1","street1 11",2,2);
INSERT INTO addressesB (city,buildingNumber) VALUES ("city","15");
INSERT INTO addressesB (city,buildingNumber) VALUES ("city 1","11");
INSERT INTO logsA (userId) VALUES (2);
INSERT INTO logsA (userId) VALUES (3);

所需结果:脚本从usersA表中选择用户,检查usersB表中的用户。如果在usersA表(so,uid)中有一条记录与kliment_number与PRIMARY KEY相同,那么它将更新,否则将插入。在地址表中也是如此。

谢谢您的帮助!

解决方法

也许您正在追求这样的东西:

INSERT INTO usersB 
(username,mobile,email,city,street,klient_number) 
SELECT username,CONCAT_WS(' ',number),uid 
  FROM usersA a 
    ON DUPLICATE KEY 
UPDATE username = a.username,mobile = a.mobile,email = a.email,city = a.city,street = CONCAT_WS(' ',a.street,a.number),klient_number = a.uid;

Query OK,3 rows affected,1 warning (0.00 sec)
Records: 3  Duplicates: 1  Warnings: 0

SELECT * FROM usersB;
+----+------------+--------+----------------------+--------------+------------+---------------+----------------+
| id | username   | mobile | email                | city         | street     | klient_number | contactAddress |
+----+------------+--------+----------------------+--------------+------------+---------------+----------------+
|  1 | John Smith | 0000   | john.smith@gmail.com | city         | street 15  |             1 |              1 |
|  2 | Kate Smith | 0000   | kate.smith@gmail.com | city_updated | street1 11 |             2 |              2 |
|  3 | Will Smith | 0000   | will.smith@gmail.com | city2        | street2 6  |             3 |              0 |
+----+------------+--------+----------------------+--------------+------------+---------------+----------------+