Seltsame Frage. ich bin Einfügen 10.000 Datensätze oder so in einer Tabelle und der Primärschlüssel ist kein Identitätsfeld. so beim Einfügen alle 10.000, wenn einige doppelt sind, gibt es eine Möglichkeit, zum nächsten Datensatz in Sql Server einfügen zu überspringen und stellen Sie sicher, dass die Nicht-Duplikate in gehen? ich wirklich nicht bout die Duplikate nicht eingefügt bekommen.
Antworten
Zu viele Anzeigen?Verwenden Sie die Option "Schlüsselduplikat ignorieren".
Der einfachste Weg, dies zu tun, ist das Löschen des Primärschlüssels in SQL Server Management Studio.
Erstellen Sie dann einen neuen Index vom Typ "Index", setzen Sie "Is Unique" auf "Yes" und setzen Sie "Ignore Duplicate Keys" auf "Yes". Fügen Sie dann Ihre Datensätze ein. Es werden alle eingefügt, außer den Duplikaten. Wenn Sie fertig sind, können Sie diesen Index löschen und Ihren Primärschlüssel neu erstellen.
Wenn Sie eine TSQL-Methode wünschen, sehen Sie sich die IGNORE_DUP_KEY-Option im CREATE INDEX-Aufruf an:
EDIT :
Eine andere Möglichkeit wäre ein LEFT JOIN zwischen Ihrer Quelltabelle und den einzufügenden Datensätzen sowie eine GROUP BY-Klausel, mit der nur Datensätze eingefügt werden, die in Ihrer Quelltabelle nicht vorhanden sind. Durch die GROUP BY-Klausel werden die Duplikate in den neuen Datensätzen eliminiert.
Müssen Sie Ihren Primärschlüssel so definieren, dass Duplikate ignoriert werden:
CREATE TABLE [dbo].[t2](
[n] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[n] ASC
)WITH (IGNORE_DUP_KEY = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Die Verwendung dieser Option kann die Leistung beeinträchtigen:
Wenn Ihre Daten einen geringen Prozentsatz an Duplikaten aufweisen, kann IGNORE_DUP_KEY Ihre Einfügungen beschleunigen. Bei einer größeren Anzahl von Duplikaten kann IGNORE_DUP_KEY diese erheblich verlangsamen. Ich habe zwei Tabellen eingerichtet und alle irrelevanten Details entfernt, wie folgt:
CREATE TABLE t1(n INT NOT NULL PRIMARY KEY)
GO
CREATE TABLE [dbo].[t2](
[n] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[n] ASC
)WITH (IGNORE_DUP_KEY = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Wenn die eingehenden Daten keine Duplikate enthielten, war die Leistung beider Einfügungen durchweg gleich:
INSERT t1(n)
SELECT n FROM dbo.Numbers
INSERT t2(n)
SELECT n FROM dbo.Numbers
(Beachten Sie, dass dbo. Numbers 1 Million Zeilen hat.) Natürlich habe ich beide Tabellen zwischen meinen Tests immer abgeschnitten.
Wenn die eingehenden Daten 1 % Duplikate aufwiesen, war die Einfügung mit IGNORE_DUP_KEY durchweg etwa 5 % schneller:
INSERT t1(n)
SELECT DISTINCT n FROM(
SELECT n FROM dbo.Numbers
UNION ALL
SELECT n FROM dbo.Numbers WHERE n <10000
) AS t
INSERT t2(n)
SELECT n FROM dbo.Numbers
UNION ALL
SELECT n FROM dbo.Numbers WHERE n <10000
Hatten die eingehenden Daten dagegen 100 % Duplikate, war die Einfügung mit IGNORE_DUP_KEY durchweg mindestens 300 % langsamer, und zwar für eine große Menge von 2 Millionen Zeilen:
INSERT t1(n)
SELECT DISTINCT n FROM(
SELECT n FROM dbo.Numbers
UNION ALL
SELECT n FROM dbo.Numbers
) AS t
INSERT t2(n)
SELECT n FROM dbo.Numbers
UNION ALL
SELECT n FROM dbo.Numbers
Sowie für einen kleineren Satz von 200K Zeilen:
INSERT t1(n)
SELECT DISTINCT n FROM(
SELECT n FROM dbo.Numbers WHERE n<100000
UNION ALL
SELECT n FROM dbo.Numbers WHERE n<100000
) AS t
INSERT t2(n)
SELECT n FROM dbo.Numbers WHERE n<100000
UNION ALL
SELECT n FROM dbo.Numbers WHERE n<100000
Insgesamt habe ich beschlossen, IGNORE_DUP_KEY in meinem speziellen Fall nicht zu verwenden. Ich bin zu dem Schluss gekommen, dass die geringen Einsparungen bei einer geringen Anzahl von Duplikaten das Risiko eines enormen Leistungsabfalls bei größeren Mengen von doppelten Daten nicht rechtfertigen.
Da ich nicht weiß, welchen Mechanismus Sie für das Einfügen verwenden, fallen mir mehrere Möglichkeiten ein.
1) Laden Sie alle Datensätze in eine neue, leere Tabelle, und führen Sie dann von dieser Staging-Tabelle aus ein INSERT in die echte Tabelle durch, wenn der Datensatz nicht bereits in der Haupttabelle vorhanden ist. z.B..
INSERT MyRealTable (PKField, Field1)
SELECT x.PKField, x.Field1
FROM MyStagingTable x
LEFT JOIN MyRealTable r ON x.PKField = r.PKField
WHERE r.PKField IS NULL
2) wickeln Sie jeden Einsatz in ein TRY...CATCH Block, um den PK-Constraint-Fehler zu schlucken, falls er auftritt (wenn Sie SQL 2005 oder später verwenden).