I haben Werte in eine Tabelle mit diesen Spalten einzufügen: wird Id
MasterId
ZipCode
Locality
Value
, CreatedTime
, UpdatedTime
Kann ich nur einfügen, wenn ein Datensatz in einer einzelnen Anweisung nicht existiert?
Ein eindeutiger Wert, der durch diese 3 Spalten definiert: MasterId
ZipCode
Locality
Es gibt keine eindeutige Einschränkung auf die Datenbank über diese Spalten, aber ich muss sicherstellen, dass 2 Benutzer nicht die gleichen Daten eingeben können. Ich kann keine Änderungen am T-SQL-Datenbankschema vornehmen.
Aktuelle SQL:
INSERT INTO dbo.Carrier VALUES (?, ?, ?, ?, ?, GETDATE(), GETDATE())
My SQL Änderungen:
IF NOT EXISTS
(
SELECT TOP 1 *
FROM dbo.Carrier
WHERE MasterId = ?
AND ZipCode = ?
AND Locality = ?
)
BEGIN
INSERT INTO dbo.Carrier VALUES (?, ?, ?, ?, ?, GETDATE(), GETDATE())
END
Diese Änderungen arbeiten für Standardbenutzereingabe, aber es gibt auch einen Service, der viele Einträge gleichzeitig einfügt. Manchmal versucht dieser Dienst, Tausende der gleichen eindeutigen Zeilen multithreadweise einzufügen, und das SQL hat eine Racebedingung, da es sich nicht um eine Anweisung handelt. Dadurch können Duplikate eingegeben werden, wenn 2 Anweisungen gleichzeitig ausgeführt werden.
Gibt es eine Möglichkeit, nur einzufügen, wenn ein Datensatz in einer einzelnen Anweisung nicht existiert?
Ich habe dieses Problem nicht auf UPDATE, weil ich kann eine wo UpdatedTime
hat sich nicht geändert.
Merge-Anweisung https://msdn.microsoft.com/en-us/library/bb510625(v=sql.110).aspx – Phritzy
Die 'top 1 "sollte mit einer' exists'-Klausel völlig überflüssig sein und vielleicht ein paar zusätzliche Nano-Sekunden Aufwand für das Parsen der Abfrage verursachen. –
Eigentlich ist es nicht garantiert, dass es auch mit Standard-Benutzereingaben funktioniert, es ist nur viel schwieriger, die Race Condition zu treffen. –