Sie sagen nicht, welche Version von SQL Server. Wenn SQL Server 2008 können Sie MERGE
NB verwenden: Es ist üblich, für eine Upsert verwenden Merge das ist, was ursprünglich dachte, dass ich die Frage stellt, aber es gilt ohne WHEN MATCHED
Klausel und nur mit einer WHEN NOT MATCHED
Klausel so funktioniert auch für diesen Fall. Beispiel Verwendung.
CREATE TABLE #A(
[id] [int] NOT NULL PRIMARY KEY CLUSTERED,
[C] [varchar](200) NOT NULL)
MERGE #A AS target
USING (SELECT 3, 'C') AS source (id, C)
ON (target.id = source.id)
/*Uncomment for Upsert Semantics
WHEN MATCHED THEN
UPDATE SET C = source.C */
WHEN NOT MATCHED THEN
INSERT (id, C)
VALUES (source.id, source.C);
In Bezug auf die Ausführung kostet die beiden in etwa gleich aussehen, wenn ein Insert zu tun ist ...
Link to plan images for first run
aber auf dem zweiten Durchlauf, wenn kein Einsatz ist Matthäus zu tun Antwort sieht niedriger aus. Ich bin mir nicht sicher, ob es eine Möglichkeit gibt, dies zu verbessern.
Link to plan images for second run
Test Script
select *
into #testtable
from master.dbo.spt_values
CREATE UNIQUE CLUSTERED INDEX [ix] ON #testtable([type] ASC,[number] ASC,[name] ASC)
declare @name nvarchar(35)= 'zzz'
declare @number int = 50
declare @type nchar(3) = 'A'
declare @low int
declare @high int
declare @status int = 0;
MERGE #testtable AS target
USING (SELECT @name, @number, @type, @low, @high, @status) AS source (name, number, [type], low, high, [status])
ON (target.[type] = source.[type] AND target.[number] = source.[number] and target.[name] = source.[name])
WHEN NOT MATCHED THEN
INSERT (name, number, [type], low, high, [status])
VALUES (source.name, source.number, source.[type], source.low, source.high, source.[status]);
set @name = 'yyy'
IF NOT EXISTS
(SELECT *
FROM #testtable
WHERE [type] = @type AND [number] = @number and name = @name)
BEGIN
INSERT INTO #testtable
(name, number, [type], low, high, [status])
VALUES (@name, @number, @type, @low, @high, @status);
END
Haben Sie überlegt, eine Eindeutigkeitsbedingung hinzuzufügen? – bmm6o