英文:
Why merge statement inserts all the data into the target table each time it runs?
问题
I have these two table with same schema and records on different server and databases.
If the record in source table gets added or modified then it should be reflected in the target table as well but for some weird reasons it inserts all the rows in the target table each time.
I just want it to insert if a new row gets added in the source or modified in the source.
Code:
MERGE INTO dbo.CountrySourceType AS target
USING (
SELECT Id = Id * (- 1)
, Name
, (
SELECT Id
FROM country c
WHERE ISNULL(c.Name, '') = (
SELECT ISNULL(cs.Name, '') Name
FROM [192.xxx.x.xxx].WebPortal.dbo.Country cs
WHERE cs.Id = cst.CountryId
)
AND ISNULL(c.ContinentName, '') = (
SELECT ISNULL(cs.ContinentName, '') ContinentName
FROM [192.xxx.x.xxx].WebPortal.dbo.Country cs
WHERE cs.Id = cst.CountryId
)
) CountryId
FROM [192.xxx.x.xxx].WebPortal.dbo.CountrySourceType cst
WHERE CountryId = cst.CountryId
) AS source
ON source.Id = target.Id
WHEN NOT MATCHED BY target
THEN
INSERT (
[Name],
[CountryId]
)
VALUES (
source.Name
,source.CountryId
);
I tried it using the merge and narrowed down using the where clause but still it doesn't.
英文:
I have these two table with same schema and records on different server and databases.
If the record in source table gets added or modified then it should be reflected in the target table as well but for some weird reasons it inserts all the rows in the target table each time.
I just want it to insert if new row gets added in the source or modified in the source.
Code:
MERGE INTO dbo.CountrySourceType AS target
USING (
SELECT Id = Id * (- 1)
, Name
, (
SELECT Id
FROM country c
WHERE ISNULL(c.Name, '') = (
SELECT ISNULL(cs.Name, '') Name
FROM [192.xxx.x.xxx].WebPortal.dbo.Country cs
WHERE cs.Id = cst.CountryId
)
AND ISNULL(c.ContinentName, '') = (
SELECT ISNULL(cs.ContinentName, '') ContinentName
FROM [192.xxx.x.xxx].WebPortal.dbo.Country cs
WHERE cs.Id = cst.CountryId
)
) CountryId
FROM [192.xxx.x.xxx].WebPortal.dbo.CountrySourceType cst
WHERE CountryId = cst.CountryId
) AS source
ON source.Id = target.Id
WHEN NOT MATCHED BY target
THEN
INSERT (
[Name],
[CountryId]
)
VALUES (
source.Name
,source.CountryId
);
I tried it using the merge and narrowed down using the where clause but still it doesn't.
答案1
得分: 0
尽量避免MERGE。通常,您可能会遇到性能问题(以及其他问题)。您可以简单地将source
添加到临时表中,然后自行执行更新和插入操作。
DROP TABLE IF EXISTS #temp_table;
SELECT Id = Id * (-1)
, Name
, (
SELECT Id
FROM country c
WHERE ISNULL(c.Name, '''') = (
SELECT ISNULL(cs.Name, '''') Name
FROM [192.xxx.x.xxx].WebPortal.dbo.Country cs
WHERE cs.Id = cst.CountryId
)
AND ISNULL(c.ContinentName, '''') = (
SELECT ISNULL(cs.ContinentName, '''') ContinentName
FROM [192.xxx.x.xxx].WebPortal.dbo.Country cs
WHERE cs.Id = cst.CountryId
)
) CountryId
INTO #temp_table
FROM [192.xxx.x.xxx].WebPortal.dbo.CountrySourceType cst
WHERE CountryId = cst.CountryId
UPDATE dbo.CountrySourceType
SET name = B.name
,County_id = B.CountryId
FROM dbo.CountrySourceType A
INNER JOIN #temp_table B
ON A.[Id] = B.[Id];
INSERT INTO dbo.CountrySourceType ([Name],[CountryId])
SELECT A.name, A.CountryId
FROM #temp_table A
LEFT JOIN dbo.CountrySourceType B
ON A.[Id] = B.[Id]
WHERE B.[Id] IS NULL;
INSERT INTO dbo.CountrySourceType ([Name],[CountryId])
SELECT A.name, A.CountryId
FROM #temp_table A
LEFT JOIN dbo.CountrySourceType B
ON A.[Name] = B.[Name]
AND A.[CountryId] = B.[CountryId]
WHERE B.[Id] IS NULL;
英文:
Try to avoid MERGE. Generally, you may have performances issues (among the other issues). You can simply add the source
in a temporary table and just perform the update and insert by yourself.
DROP TABLE IF EXISTS #temp_table;
SELECT Id = Id * (- 1)
, Name
, (
SELECT Id
FROM country c
WHERE ISNULL(c.Name, '') = (
SELECT ISNULL(cs.Name, '') Name
FROM [192.xxx.x.xxx].WebPortal.dbo.Country cs
WHERE cs.Id = cst.CountryId
)
AND ISNULL(c.ContinentName, '') = (
SELECT ISNULL(cs.ContinentName, '') ContinentName
FROM [192.xxx.x.xxx].WebPortal.dbo.Country cs
WHERE cs.Id = cst.CountryId
)
) CountryId
INTO #temp_table
FROM [192.xxx.x.xxx].WebPortal.dbo.CountrySourceType cst
WHERE CountryId = cst.CountryId
UPDATE dbo.CountrySourceType
SET name = B.name
,County_id = B.CountryId
FROM dbo.CountrySourceType A
INNER JOIN #temp_table B
ON A.[Id] = B.[Id];
INSERT INTO dbo.CountrySourceType ([Name],[CountryId])
SELECT A.name, A.CountryId
FROM #temp_table A
LEFT JOIN dbo.CountrySourceType B
ON A.[Id] = B.[Id]
WHERE B.[Id] IS NULL;
INSERT INTO dbo.CountrySourceType ([Name],[CountryId])
SELECT A.name, A.CountryId
FROM #temp_table A
LEFT JOIN dbo.CountrySourceType B
ON A.[Name] = B.[Name]
AND A.[CountryId] = B.[CountryId]
WHERE B.[Id] IS NULL;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论