Wie ein ausgewähltes Ergebnis einer Variablen zugewiesen werden?
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:
- bekommt Liste der Rechnungen IDs von Rechnungstabelle und speichert Cursor
- Fetch Rechnung id von Cursor -> tmp_key Variable
- foreach tmp_key findet Rechnung Client primäre Kontakt-ID von Kundentabelle
- aktualisiert den Client-Kontaktschlüssel mit primärer Kontakt-ID
- 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?
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