Ist ein Cursor die einzige Alternative, um diese Art von Operation zu tun

Ich versuche, eine lange Transaktion zu optimieren und ich habe gesehen, dass das Folgende schon ein paar Mal getan wird:

Declare @myCursor CURSOR FAST_FORWARD FOR SELECT field1, MIN(COALESCE(field2, -2)) FROM MyTable tempfact LEFT JOIN MyTable sd ON tempfact.ID = sd.ID AND sd.TransactionId = @transactionId WHERE tempfact.SomeField IS NULL AND tempfact.TransactionId = @transactionId GROUP BY tempfact.field1 OPEN @myCursor FETCH NEXT FROM @myCursor INTO @field1Variable, @field2Variable WHILE @@FETCH_STATUS = 0 BEGIN EXEC USP_SOME_PROC @field1Variable, @field2Variable FETCH NEXT FROM @myCursor INTO @field1Variable, @field2Variable END CLOSE @myCursor DEALLOCATE @myCursor 

Der Code für den USP_SOME_PROC Sproc lautet wie folgt:

 IF NOT EXISTS (SELECT * FROM SomeTable WHERE Field1 = @field1) BEGIN INSERT INTO SomeTable (Field1, Field2) VALUES (@field1, @field2) END 

Wie ich schon erwähnt habe, ist das an einigen Orten getan, Tabellen und Felder sind anders, aber die Idee bleibt gleich, und ich bin mir sicher, dass es einen path geben könnte, die performance dieser Sprossen zu erhöhen, wenn Cursor nicht benutzt werden und wahrscheinlich indem ich diese Transaktion schneller ein Problem mache, das wir mit einem Deadlock (ein Thema für einen anderen Post) haben, könnte getriggers werden.

Sie können dazu MERGE

 ;WITH Source AS ( SELECT field1, MIN(COALESCE(field2, -2)) as field2 FROM MyTable tempfact LEFT JOIN MyTable sd ON tempfact.ID = sd.ID AND sd.TransactionId = @transactionId WHERE tempfact.SomeField IS NULL AND tempfact.TransactionId = @transactionId GROUP BY tempfact.field1 ) MERGE SomeTable AS T USING Source S ON (T.Field1 = S.Field1) WHEN NOT MATCHED BY TARGET THEN INSERT (Field1, Field2) VALUES (field1, field2) ; 

Ich habe keine Chance gehabt, dies zu testing, aber das sollte in der Nähe sein: Du musst aus einer SELECT-statement insert, musst aber auch dafür sorgen, dass ein entsprechender datasatz in SomeTable noch nicht existiert

 INSERT INTO SomeTable (Field1, Field2) SELECT field1, MIN(COALESCE(field2, -2)) FROM MyTable tempfact LEFT JOIN MyTable sd ON tempfact.ID = sd.ID AND sd.TransactionId = @transactionId LEFT JOIN SomeTable st ON st.Field1 = tempfact.field1 WHERE tempfact.SomeField IS NULL AND tempfact.TransactionId = @transactionId AND st.Field1 IS NULL GROUP BY tempfact.field1 

Sie brauchen keinen Cursor und können die Bulk-Insert-Logik so etwas wie unten verwenden

 INSERT INTO SomeTable (Field1, Field2) SELECT field1, MIN(COALESCE(field2, -2)) FROM MyTable tempfact LEFT JOIN MyTable sd ON tempfact.ID = sd.ID AND sd.TransactionId = @transactionId WHERE tempfact.SomeField IS NULL AND tempfact.TransactionId = @transactionId GROUP BY tempfact.field1 

Hoffe das hilft!!