我的“合并”问题: MERGE语句尝试多次更新或删除同一行。
有人可以帮我解决这个问题,因为我不明白如何纠正这个问题:
ALTER PROCEDURE [Files].[ImportFiles]
AS
-- Create a temporary table for the bulk import
CREATE TABLE #TempImportFileTable(
[fileID] [bigint] IDENTITY(1,1) NOT NULL,
[FileName] [nvarchar](max) NULL,
[FilePath] [nvarchar](max) NULL,
[FullPath] [nvarchar](max) NULL,
[FileSize] [nvarchar](max) NULL,
[FileExtension] [nvarchar](max) NULL,
[FileCreated] [nvarchar](max) NULL,
[FileLastAccessed] [nvarchar](max) NULL,
[FileModified] [nvarchar](max) NULL
CONSTRAINT [PK_fileID1] PRIMARY KEY CLUSTERED
(
[fileID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY];
-- Import into the temp table
BULK INSERT #TempImportFileTable FROM 'C:\Program Files\o7th FileSystem to DB\import.txt'
WITH(KEEPIDENTITY, FIELDTERMINATOR =',', ROWTERMINATOR = '\n');
-- Delete the Duplicate entries
DELETE FROM #TempImportFileTable WHERE fileID NOT IN (SELECT MAX(fileID) FROM #TempImportFileTable GROUP BY FullPath);
-- Now Merge the 2 tables
MERGE [Files].[File] AS TargetTable
USING #TempImportFileTable AS SourceTable
ON (TargetTable.FullPath = SourceTable.FullPath)
WHEN NOT MATCHED BY TARGET
THEN INSERT (FileName, FilePath, FileSize, FileExtension, FileCreated, FileLastAccessed, FileModified)
VALUES(SourceTable.FileName, SourceTable.FilePath, SourceTable.FileSize, SourceTable.FileExtension, SourceTable.FileCreated, SourceTable.FileLastAccessed, SourceTable.FileModified)
WHEN MATCHED
THEN UPDATE SET
TargetTable.FileName = SourceTable.FileName,
TargetTable.FilePath = SourceTable.FilePath,
TargetTable.FileSize = SourceTable.FileSize,
TargetTable.FileExtension = SourceTable.FileExtension,
TargetTable.FileCreated = SourceTable.FileCreated,
TargetTable.FileLastAccessed = SourceTable.FileLastAccessed,
TargetTable.FileModified = SourceTable.FileModified;
答案 0 :(得分:1)
所以你的#TempFileTable中有重复项。
如果FileName + FilePath足以使行唯一,则可以将此条件用于MERGE:
MERGE [Files].[File] AS TargetTable
USING #TempFileTable AS SourceTable
ON (
ISNULL(TargetTable.FileName,'') = ISNULL(SourceTable.FileName,'')
AND ISNULL(TargetTable.FileName,'') = ISNULL(SourceTable.FileName,'')
)
(我不知道为什么ISNULL()函数在你之前尝试调用它时不起作用,但它肯定应该以这种方式工作,并处理空值出现的问题。)
如果您的原始文件中确实存在重复的行并且想要删除它们,则可以使用此类代码:
DELETE FROM #TempFileTable WHERE fileID IN (
SELECT u.fileID FROM(
select fileID, ROW_NUMBER() OVER(PARTITION BY FileName, FilePath OVER fileID) as r_number
FROM #TempFileTable
) where u.r_number>1
)
很难看,但是当多行具有相同的FileName和相同的FilePath时,它将删除具有最高fileID的行并且只保留一行。
编辑:关于性能问题,首先尝试查看估计的执行计划,看看是否可以向表中添加索引。您还可以尝试将MERGE过程分解为INSERT和一个UPDATE语句。 MERGE应该更好,但在某些情况下,它实际上比单独的陈述更糟糕。
答案 1 :(得分:0)
合并语句有一个限制,即它不能多次更新同一行,或者更新和删除同一行。因此,请确保源数据中包含带有文件名的不同行。 此外,在进行更新时,您不必更新文件名列,因为它在源表和目标表中都是相同的。
您可以通过以下链接找到解决方法:http://support.microsoft.com/kb/976316