2013-08-13 3 views
0

"병합"에 문제가 있습니다. MERGE 문에서 동일한 행을 두 번 이상 UPDATE 또는 DELETE하려고했습니다. 병합 문이 여러 번 같은 행 이상을 업데이트하거나 업데이트하고 삭제할 수 없습니다 제한이 있습니다대량 주입 Sproc에서 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

데이터 파일에 중복 된 항목이 있습니까? – podiluska

+1

"MERGE 문이 동일한 행을 두 번 이상 UPDATE 또는 DELETE하려고했습니다." 이것이 의미하는 바는 #TempFileTable의 한 행 이상이 [Files]. [File]의 한 행과 일치한다는 것입니다. Merge 문은 [Files]. [File]을 업데이트하는 데 사용할 행을 알지 못하므로 오류를 반환합니다. FileName이 아닌 고유 한 항목에 대해 일치를 시도 할 수 있습니다. 그런데 fileName 필드가 nullable 인 것 같습니다. 그래서 일치 조건을 (ISNULL (TargetTable.FileName, '') = ISNULL (SourceTable.FileName, ''))로 대체 할 수 있습니다. –

+0

파일이 이미 테이블에 존재하는지 확인하기 위해 FileName을 일치시킬 수 있어야합니다. – Kevin

답변

1

그래서 당신은 당신의 #TempFileTable에 중복이있다.

파일 이름 + FilePath를이 행을 고유하게 만들기에 충분했다 경우

, 당신은 당신의 병합에이 조건을 사용할 수
MERGE [Files].[File] AS TargetTable 
    USING #TempFileTable AS SourceTable 
    ON ( 
     ISNULL(TargetTable.FileName,'') = ISNULL(SourceTable.FileName,'') 
     AND ISNULL(TargetTable.FileName,'') = ISNULL(SourceTable.FileName,'') 
    ) 

(나는 모르는 ISNULL() 기능을 사용하면 작동하지 않는 이유 이전에이를 호출하려고 시도했지만이 방법으로 확실히 작동해야하며 null 값으로 발생하는 문제를 처리해야합니다.

원본 파일에 실제로 중복 행이 있고이를 제거하려는 경우 다음과 같은 종류의 코드를 사용하십시오 :

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가있는 경우 파일 ID가 가장 높은 행을 제거하고 하나만 유지합니다.

편집 : 성능 문제에 대해서는 먼저 예상 실행 계획을보고 테이블에 인덱스를 추가 할 수 있는지 확인하십시오. 또한 MERGE 프로 시저를 INSERT 및 UPDATE 문으로 나눌 수 있습니다. MERGE는 더 좋을 수 있지만 상황에 따라 실제로는 별도의 명령문보다 나쁩니다.

+0

정말 고마워요. 실제로 전체 파일 경로와 이름을 포함하도록 import.txt 파일을 만드는 코드가 변경되었으므로, 속임수를 써라. 또한 테스트 선택 시나리오에서 DELETE FROM #TempImportFileTable where fileID NOT (SELECT MAX (fileID) FROM #TempImportFileTable GROUP BY FullPath);을 사용하여 트릭을 수행하는 것처럼 보였습니다. 내 "DELETE"문에 대한 사용자의 이점은 무엇입니까? – Kevin

+0

DELETE 문이 더 좋지 않습니다. 나는 최근에 너무 많은 ROW_NUMBER()를 사용 해왔고, 모든 문제에 대한 최선의 해결책이 아닌 것을 잊어 버리는 경향이 있습니다. -_-. –

+0

여전히 작동하지 않습니다. 심지어 내 것과 함께, 그것과 폭탄에 약 7 분을 얻는다. – Kevin

0

:

누군가 내가 문제를 해결하는 방법을 이해하지 않는 나를,이 문제를 해결하는 데 도움을 줄 수 있습니다 같은 행. 따라서 원본 데이터에서 파일 이름이 다른 행이 있는지 확인하십시오. 또한 업데이트를 수행하는 동안 원본 테이블과 대상 테이블에서 파일 이름 열이 동일하게 업데이트되므로 파일 이름 열을 업데이트 할 필요가 없습니다.

당신은이 링크에 주위에 작업을 얻을 수 있습니다 http://support.microsoft.com/kb/976316