【发布时间】:2020-10-30 09:49:15
【问题描述】:
我必须在 node js windows 服务中合并多个数据库表。
所以我决定写一个方法来为此创建一个 sql 字符串。
这是我的方法:
function createSQLString(targetTable, sourceTable, columns){
let sql = "MERGE " + targetTable + " AS TARGET USING " + sourceTable + " AS SOURCE \n";
switch (sourceTable) {
//.....some other cases.....
case 'communications':
sql += "ON (" +
" TARGET.[id] = SOURCE.[id]" +
" AND TARGET.[business_partner_id] = SOURCE.[business_partner_id]" +
" AND TARGET.[fiscalYear] = SOURCE.[fiscalYear]" +
") \n";
break;
default:
// other stuff
}
// if row was found and values are not equal
sql += "WHEN MATCHED AND (";
columns.forEach(column => {
sql += "SOURCE.[" + column.COLUMN_NAME + "] <> TARGET.[" + column.COLUMN_NAME + "] OR ";
})
sql = sql.substring(0, sql.length -4) + "\n";
sql += ") THEN UPDATE SET ";
columns.forEach(column => {
sql += "TARGET.[" + column.COLUMN_NAME + "] = SOURCE.[" + column.COLUMN_NAME + "],"
})
sql = sql.substring(0, sql.length -1) + "\n";
// if no match in target insert
sql += "WHEN NOT MATCHED BY TARGET THEN INSERT (";
columns.forEach(column => {
sql += "[" + column.COLUMN_NAME + "], ";
})
sql = sql.substring(0, sql.length -2) + "\n";
sql += ") VALUES ("
columns.forEach(column => {
sql += "SOURCE.[" + column.COLUMN_NAME + "], ";
})
sql = sql.substring(0, sql.length -2) + "\n";
sql += ")\n"
// if there is a record in target but not in source
sql += "WHEN NOT MATCHED BY SOURCE \n THEN DELETE;"
return sql;
}
这种方法和创建的 sql 字符串效果很好,在一种情况下除外。
如果源表列中的值为NULL,则不会更新目标。
这是该案例的屏幕截图(表 1 目标,表 2 源):
为什么不更新以及如何解决?
编辑:这里是生成的sql字符串:
MERGE communication AS TARGET USING communication_cache AS SOURCE
ON (
TARGET.[id] = SOURCE.[id] AND
TARGET.[fiscalYear] = SOURCE.[fiscalYear] AND
TARGET.[clientId] = SOURCE.[clientId]
)
WHEN MATCHED AND (
SOURCE.[id] <> TARGET.[id] OR
SOURCE.[address_type] <> TARGET.[address_type] OR
SOURCE.[is_correspondence_address] <> TARGET.[is_correspondence_address] OR
SOURCE.[is_main_post_office_box_address] <> TARGET.
[is_main_post_office_box_address] OR
SOURCE.[is_main_street_address] <> TARGET.[is_main_street_address] OR
SOURCE.[is_management_address] <> TARGET.[is_management_address] OR
SOURCE.[business_partner_id] <> TARGET.[business_partner_id] OR
SOURCE.[fiscalYear] <> TARGET.[fiscalYear]
)
THEN UPDATE SET
TARGET.[id] = SOURCE.[id],
TARGET.[address_type] = SOURCE.[address_type],
TARGET.[is_correspondence_address] = SOURCE.[is_correspondence_address],
TARGET.[is_main_post_office_box_address] = SOURCE.
[is_main_post_office_box_address],
TARGET.[is_main_street_address] = SOURCE.[is_main_street_address],
TARGET.[is_management_address] = SOURCE.[is_management_address],
TARGET.[business_partner_id] = SOURCE.[business_partner_id],
TARGET.[fiscalYear] = SOURCE.[fiscalYear]
WHEN NOT MATCHED BY TARGET THEN INSERT (
[id], [address_type], [is_correspondence_address],
[is_main_post_office_box_address], [is_main_street_address],
[is_management_address], [business_partner_id], [fiscalYear]
) VALUES (SOURCE.[id], SOURCE.[address_type], SOURCE.
[is_correspondence_address], SOURCE.[is_main_post_office_box_address],
SOURCE.[is_main_street_address], SOURCE.[is_management_address], SOURCE.
[business_partner_id], SOURCE.[fiscalYear]
)
WHEN NOT MATCHED BY SOURCE
THEN DELETE
【问题讨论】:
-
你能告诉我们最终形成的 SQL 字符串吗?这将有助于更好地分析。
标签: sql node.js sql-server sql-update sql-insert