Estoy intentando insertar muchos registros usando la instrucción MERGE de T-SQL, pero mi consulta no puede INSERTAR cuando hay registros duplicados en la tabla de origen. El fallo se debe a:Cómo evitar la inserción de registros duplicados al utilizar una instrucción de combinación de T-SQL
- la tabla de destino tiene una clave principal basado en dos columnas
- la tabla de origen puede contener registros duplicados que violan la restricción de clave principal de la tabla de destino ("Violación de restricción PRIMARY KEY" es lanzado)
Estoy buscando una forma de cambiar mi declaración MERGE para que ignore los registros duplicados dentro de la tabla fuente y/o intente capturar la instrucción INSERT para detectar excepciones que puedan ocurrir (es decir, todas otras instrucciones INSERT se ejecutarán independientemente de los pocos huevos malos que puedan ocurrir) o, tal vez, haya una mejor manera de o ¿sobre este problema?
Aquí hay un ejemplo de consulta de lo que intento explicar. El siguiente ejemplo se sumará 100 mil registros a una tabla temporal y luego intentará insertar los registros en la tabla de destino -
EDITAR En mi post original sólo incluía dos campos en el ejemplo mesas, que dio paso a SO amigos para dar una solución DISTINCT para evitar duplicados en la instrucción MERGE. Debería haber mencionado que en mi problema del mundo real las tablas tienen 15 campos y de esos 15, dos de los campos son CLAVES PRIMARIAS CLAVES. Por lo tanto, la palabra clave DISTINCT no funciona porque necesito SELECCIONAR los 15 campos e ignorar los duplicados en función de dos de los campos.
He actualizado la consulta a continuación para incluir un campo más, col4. Necesito incluir col4 en MERGE, pero solo necesito asegurarme de que SOLO col2 y col3 sean únicos.
-- Create the source table
CREATE TABLE #tmp (
col2 datetime NOT NULL,
col3 int NOT NULL,
col4 int
)
GO
-- Add a bunch of test data to the source table
-- For testing purposes, allow duplicate records to be added to this table
DECLARE @loopCount int = 100000
DECLARE @loopCounter int = 0
DECLARE @randDateOffset int
DECLARE @col2 datetime
DECLARE @col3 int
DECLARE @col4 int
WHILE (@loopCounter) < @loopCount
BEGIN
SET @randDateOffset = RAND() * 100000
SET @col2 = DATEADD(MI,@randDateOffset,GETDATE())
SET @col3 = RAND() * 1000
SET @col4 = RAND() * 10
INSERT INTO #tmp
(col2,col3,col4)
VALUES
(@col2,@col3,@col4);
SET @loopCounter = @loopCounter + 1
END
-- Insert the source data into the target table
-- How do we make sure we don't attempt to INSERT a duplicate record? Or how can we
-- catch exceptions? Or?
MERGE INTO dbo.tbl1 AS tbl
USING (SELECT * FROM #tmp) AS src
ON (tbl.col2 = src.col2 AND tbl.col3 = src.col3)
WHEN NOT MATCHED THEN
INSERT (col2,col3,col4)
VALUES (src.col2,src.col3,src.col4);
GO
Tienes que decidir qué fila debes elegir col4 cuando hay duplicados para col2 y col3 en #tmp. Por ejemplo, puede usar 'group by col2, col3' y' min (col4) como col4'. –