나는 다음과 같은 코드가 있습니다MERGE 문에서 간헐적 인 중복 업데이트 오류가 발생하는 이유는 무엇입니까?
// accessedKeys is a HashSet<string>
if (accessedKeys.Count > 0)
{
string queryFormat = @"SET NOCOUNT ON;
DECLARE @updated_resources TABLE (name varchar(512))
INSERT INTO @updated_resources (name) VALUES ('{0}')
MERGE resource_access WITH (HOLDLOCK) AS target
USING @updated_resources AS source
ON target.name = source.name
WHEN MATCHED THEN
UPDATE SET last_access = GETDATE()
WHEN NOT MATCHED THEN
INSERT (name, last_access) VALUES (source.name, GETDATE());";
string entries = String.Join("'),('", accessedKeys.Select(s => s.Replace("'", "''")));
string query = String.Format(queryFormat, entries);
using (var connection = new SqlConnection(...))
{
connection.Open();
using (var cmd = connection.CreateCommand())
{
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = query;
cmd.ExecuteNonQuery();
}
}
accessedKeys.Clear();
}
resource_access
이 같은 생성됩니다 일시적으로
CREATE TABLE resource_access (
name varchar(512) primary key,
last_access smalldatetime not null
)
을, 나는 나의 문을 실행하는 동안 다음과 같은 예외가 나타납니다
The MERGE statement attempted to UPDATE or DELETE the same row more than
once. This happens when a target row matches more than one source row. A
MERGE statement cannot UPDATE/DELETE the same row of the target table
multiple times. Refine the ON clause to ensure a target row matches at most
one source row, or use the GROUP BY clause to group the source rows.
@updated_resources.name
입니다 별개의 문자열 목록에서 채워지며 resource_access.name
은 기본 키입니다. y는 고유 한 의미이기도합니다. 두 테이블 'name
열에 모두 병합 중이며 둘 다 중복 항목이있을 수 있습니다.
예외가 발생하는 경우 accessedKeys.Distinct().Count
은 accessedKeys.Count
과 같습니다. SELECT COUNT(DISTINCT(name)) FROM resource_access
을 실행하면 테이블의 행 수와 같습니다.
때때로이 오류가 발생합니까?
좀 더미 데이터를 시도 할 것입니다, 당신은 어떻게 발생 어디에/좁힐 수없는 경우를 참조하십시오. 즉 resource_access 테이블에 'Bob'을 가지고 있으며이 경우 액세스 된 키 집합에 'Bob'과 'BOB'가 모두있어 오류의 원인인지 아닌지 확인하십시오. 다행히도 그것은 의미가 있습니다. – Trent