Wie man ein T-SQL-Cursor schneller?

Hey, ich Habe einen cursor in gespeicherten Prozeduren unter SQL Server 2000 (nicht möglich auf jetzt aktualisieren), die Aktualisierung der Tabelle, aber es dauert in der Regel einige Minuten. Ich brauche, um es schneller zu machen. Hier die Beispiel Tabelle gefiltert durch einen beliebigen Produkt-id;
Beispiel-Tabelle http://img231.imageshack.us/img231/9464/75187992.jpg
In der Erwägung, dass GDEPO:Eintrag depot, CDEPO:Ausfahrt depot,Zahl: die Zahl,E_CIKAN Menge, die verwendet wird.

Datensatz Erläuterungen:

1: 20 Einheit betritt depot 01,
2: 10 Einheit verlässt, 01.
3: 5 Unit Blätter 01 (E_CIKAN für den 1. Datensatz wird 15 jetzt)
4: 10 mehr Einheit betritt depot 01.
5: 3 Einheit verlässt, 01 ab dem 1. Datensatz. Jetzt sehen Sie den 1. Datensatz hat E_CIKAN Satz zu 18.
6: Dies ist, wo das problem kommt in: 3 Einheit verlassen muss depot 01. Es dauert 2-Einheit 1. Datensatz und 1 Einheit ab 5. Datensatz. Mein SP kann damit umgehen fein wie gesehen, in Bild, außer es ist WIRKLICH langsam.

Hier ist die gespeicherte Prozedur, die ins englische übersetzt;

CREATE PROC [dbo].[UpdateProductDetails]
as
UPDATE PRODUCTDETAILS SET E_CIKAN=0;
DECLARE @ID int
DECLARE @SK varchar(50),@DP varchar(50)  --SK = STOKKODU = PRODUCTID, DP = DEPOT
DECLARE @DEMAND float     --Demand=Quantity, We'll decrease it record by record
DECLARE @SUBID int
DECLARE @SUBQTY float,@SUBCK float,@REMAINS float
DECLARE SH CURSOR FAST_FORWARD FOR
SELECT [ID],PRODUCTID,QTY,EXITDEPOT FROM PRODUCTDETAILS  WHERE (EXITDEPOT IS NOT NULL) ORDER BY [DATE] ASC
OPEN SH
FETCH NEXT FROM SH INTO @ID, @SK,@DEMAND,@DP

WHILE (@@FETCH_STATUS = 0)
BEGIN
   DECLARE SA CURSOR FAST_FORWARD FOR
   SELECT [ID],QTY,E_CIKAN FROM PRODUCTDETAILS  WHERE (QTY>E_CIKAN) AND (PRODUCTID=@SK) AND (ENTRYDEPOT=@DP) ORDER BY [DATE] ASC
   OPEN SA
   FETCH NEXT FROM SA INTO @SUBID, @SUBQTY,@SUBCK
   WHILE (@@FETCH_STATUS = 0) AND (@DEMAND>0)
   BEGIN
      SET @REMAINS=@SUBQTY-@SUBCK
      IF @DEMAND>@REMAINS  --current record isnt sufficient, use it and move on
      BEGIN
         UPDATE PRODUCTDETAILS SET E_CIKAN=QTY WHERE ID=@SUBID;
         SET @DEMAND=@DEMAND-@REMAINS
      END
      ELSE
      BEGIN
         UPDATE PRODUCTDETAILS SET E_CIKAN=E_CIKAN+@DEMAND WHERE ID=@SUBID;
         SET @DEMAND=0
      END
      FETCH NEXT FROM SA INTO @SUBID, @SUBAD,@SUBCK
   END
   CLOSE SA
   DEALLOCATE SA
   FETCH NEXT FROM SH INTO @ID, @SK,@DEMAND,@DP
END
CLOSE SH
DEALLOCATE SH
  • Ihre Anfragen werden mit einer Reihe von Spalten, die nicht aufgeführt sind in deinem Screenshot. Es wäre wahrscheinlich besser, wenn Sie die DDL für die Tabelle zusammen mit den aktuellen Beschreibungen der Spalten.
  • Tom, ich habe übersetzt Abfrage in Englisch und sagte Whereas GDEPO:Entry depot, CDEPO:Exit depot,Adet: quantity,E_CIKAN quantity that's used. nach screenshot für Sie.
  • E_CIKAN zeigt die Menge, die verwendet wird (indem Sie die folgenden Datensätze) aus der Menge. Überprüfen Sie die ersten 3 Einträge, 20 Einstieg,10+5 Abfahrt. E_CIKAN für den 1. Datensatz wird 15 dann. Gespeicherte Prozedur tut dies nur gut, problem ist, es ist wirklich langsam.
  • (Entschuldigung, ich habe das löschen meiner Kommentare, da verstehe ich mehr). OK, ich bekomme es jetzt. So E_CIKAN zeigt wie viele der ZAHL verwendet wurden. So ist es bei 0 beginnt und dann die gespeicherte Prozedur fügt es. Also dein screenshot zeigt die letzten Werte, nachdem die Prozedur ausgeführt wurde.
  • Sie brauchen nicht eine geschachtelte cursor oder sogar einem cursor zu tun, was Sie versuchen zu tun, Sie können schreiben ein paar update-Anweisungen oder wenn seine wirklich komplexe mithilfe einer temp-Tabelle abzuleiten, manche berechnen dann tun Sie Ihr update. Aber nichts-Logik-Weise in Ihren Cursor erfordern die Verwendung von Cursorn.
Schreibe einen Kommentar