Frage

Wie speichere ich einen ausgewählten Feldwert in eine Variable aus einer Abfrage und verwenden Sie es in einer Update-Anweisung?

Hier ist mein Verfahren:

Ich schreibe eine SQL Server 2005 T-SQL gespeicherte Prozedur, die macht folgendes:

  1. bekommt Liste der Rechnungen IDs von Rechnungstabelle und speichert Cursor
  2. Fetch Rechnung id von Cursor -> tmp_key Variable
  3. foreach tmp_key findet Rechnung Client primäre Kontakt-ID von Kundentabelle
  4. aktualisiert den Client-Kontaktschlüssel mit primärer Kontakt-ID
  5. schließen Cursor

Hier ist mein Code:

DECLARE @tmp_key int
DECLARE @get_invckey cursor 

set @get_invckey = CURSOR FOR 
    select invckey from tarinvoice where confirmtocntctkey is null and tranno like '%115876'

OPEN @get_invckey 

FETCH NEXT FROM @get_invckey into @tmp_key

WHILE (@@FETCH_STATUS = 0) 
BEGIN 
    SELECT c.PrimaryCntctKey as PrimaryContactKey
    from tarcustomer c, tarinvoice i
    where i.custkey = c.custkey and i.invckey = @tmp_key

    UPDATE tarinvoice set confirmtocntctkey = PrimaryContactKey where invckey = @tmp_key
    FETCH NEXT FROM @get_invckey INTO @tmp_key
END 

CLOSE @get_invckey
DEALLOCATE @get_invckey

Wie speichere ich die PrimaryContactKey und verwenden Sie es erneut in der SET-Klausel der folgenden Update-Anweisung? Muss ich einen Cursor Variable erstellen oder einfach nur eine weitere lokale Variable mit einem int-Typ?

War es hilfreich?

Lösung

DECLARE @tmp_key int
DECLARE @get_invckey cursor 

SET @get_invckey = CURSOR FOR 
    SELECT invckey FROM tarinvoice WHERE confirmtocntctkey IS NULL AND tranno LIKE '%115876'

OPEN @get_invckey 

FETCH NEXT FROM @get_invckey INTO @tmp_key

DECLARE @PrimaryContactKey int --or whatever datatype it is

WHILE (@@FETCH_STATUS = 0) 
BEGIN 
    SELECT @PrimaryContactKey=c.PrimaryCntctKey
    FROM tarcustomer c, tarinvoice i
    WHERE i.custkey = c.custkey AND i.invckey = @tmp_key

    UPDATE tarinvoice SET confirmtocntctkey = @PrimaryContactKey WHERE invckey = @tmp_key
    FETCH NEXT FROM @get_invckey INTO @tmp_key
END 

CLOSE @get_invckey
DEALLOCATE @get_invckey

EDIT:
Diese Frage hat sich viel mehr Traktion bekommen, als ich erwartet hätte. Merken Sie, dass ich nicht die Verwendung des Cursors in meiner Antwort befürworten, sondern zeigt, wie der Wert zuweisen basierend auf der Frage.

Andere Tipps

Ich hatte gerade das gleiche Problem und ...

declare @userId uniqueidentifier
set @userId = (select top 1 UserId from aspnet_Users)

oder noch kürzer:

declare @userId uniqueidentifier
SELECT TOP 1 @userId = UserId FROM aspnet_Users

Try This

SELECT @PrimaryContactKey = c.PrimaryCntctKey
FROM tarcustomer c, tarinvoice i
WHERE i.custkey = c.custkey 
    AND i.invckey = @tmp_key

UPDATE tarinvoice SET confirmtocntctkey = @PrimaryContactKey 
WHERE invckey = @tmp_key
FETCH NEXT FROM @get_invckey INTO @tmp_key

Sie würden diese Variable deklarieren außerhalb der Schleife als nur ein Standard TSQL Variable.

Ich sollte auch beachten Sie, dass dies ist, wie Sie es für jede Art von Auswahl in eine Variable tun würde, nicht nur, wenn sie mit Cursor zu tun.

Warum brauchen Sie einen Cursor überhaupt? Ihr gesamtes Codesegment kann durch diese ersetzt werden, was viel schneller auf eine große Anzahl von Zeilen ausgeführt wird.

UPDATE tarinvoice set confirmtocntctkey = PrimaryCntctKey 
FROM tarinvoice INNER JOIN tarcustomer ON tarinvoice.custkey = tarcustomer.custkey
WHERE confirmtocntctkey is null and tranno like '%115876'

Um eine Variable zuweisen sicher müssen Sie die SET-SELECT-Anweisung verwenden:

SET @PrimaryContactKey = (SELECT c.PrimaryCntctKey
    FROM tarcustomer c, tarinvoice i
    WHERE i.custkey = c.custkey 
    AND i.invckey = @tmp_key)

Vergewissern Sie sich, sowohl eine Start- und eine End-Klammer!

Der Grund für die SET-SELECT-Version ist der sicherste Weg, um eine Variable zu setzen ist ein doppeltes.

1. Die SELECT gibt mehrere Beiträge

Was passiert, wenn die folgenden Auswahlergebnisse in mehreren Beiträgen benutzen?

SELECT @PrimaryContactKey = c.PrimaryCntctKey
FROM tarcustomer c, tarinvoice i
WHERE i.custkey = c.custkey 
    AND i.invckey = @tmp_key

@PrimaryContactKey wird der Wert aus der letzten Beitrag zugeordnet werden im Ergebnis.

In der Tat @PrimaryContactKey wird einen Wert pro Eintrag in dem Ergebnis zugeordnet werden, so dass es folglich den Wert des letzten Beitrags der SELECT-Befehl wurde die Verarbeitung enthalten wird.

Welche Stelle ist „last“ von irgendwelchen Clustered-Indizes bestimmt wird, oder, wenn kein Clustered-Index verwendet wird oder der Primärschlüssel gruppiert ist, das „letzte“ Post wird die zuletzt hinzugefügten Post. Dieses Verhalten könnte im schlimmsten Fall wird jedes Mal geändert werden, die Indizierung der Tabelle geändert.

Mit einer SET-Anweisung SELECT Ihre Variablen gesetzt werden null.

2. Die SELECT liefert keine Beiträge

Was passiert, wenn die zweite Version des Codes verwenden, wenn Ihr wählen Sie kein Ergebnis überhaupt zurückkehren?

In einem im Gegensatz zu dem, was Sie den Wert der Variablen glauben nicht null sein - es behält es ist vorheriger Wert

Das ist, weil, wie oben erwähnt, SQL Wert der Variablen zugewiesen werden einmal per Post - Was bedeutet es nichts mit den Variablen tun wird, wenn das Ergebnis keine Beiträge enthält. So wird die Variable immer noch den Wert hat es hatte, bevor Sie die Anweisung ausgeführt wird.

Mit der SET-SELECT-Anweisung wird der Wert null werden.

Siehe auch: gegen SELECT SET, wenn Variablen zuweisen

scroll top