2017-06-09 4 views
-1

Hallo Ich bin ein wenig verwirrt, um das SQL Server-Verhalten beim Ausführen der Abfrage zu sehen. Nach Mine sollte der Ausgang "Priyanka", 4SQL Server-Problem während des Updates

Declare @temp table(
Name Varchar(50), 
amount int 
) 

insert @temp values ('Priyanka' ,10) 

Update @temp 
set amount=amount-A.a 
from (
select 'Priyanka' as Name,1 as a 
union 
select 'Priyanka' as Name,5 as a 
)A 
where [@temp].Name in (A.Name) 

select * from @temp 

Aber der Ausgang

Name amount 
Priyanka 9 

sein Kann mir bitte erklären, warum dies geschehen ist.

Antwort

0

Standard-SQL keine from Klausel mit update unterstützen und Sie würden stattdessen den Zugriff auf andere Tabellen als direkte Unterabfrage in der set Klausel zu schreiben. Wenn Sie das tun würden, würden Sie den Fehler "Unterabfrage gab mehr als einen Wert" erhalten und eine Vorstellung von dem Problem haben.

Leider ist die Microsoft-Erweiterung zu SQL, die ermöglicht eine FROM Klausel auch leise ignoriert die Tatsache, dass mehrere Zeilen anzeigen lassen kann, verwendet eine dieser Zeilen und ignoriert die anderen.

Wenn Sie diese Erweiterung verwenden möchten, müssen Sie sorgfältig darauf achten, dass Sie nicht mehrere Übereinstimmungen mit einer einzelnen Zeile in der Zieltabelle haben.

ich Ihre Abfrage neu anordnen würde, so etwas wie:

Declare @temp table(
Name Varchar(50), 
amount int 
) 

insert @temp values ('Priyanka' ,10) 

;With A as 
(
select 'Priyanka' as Name,1 as a 
union 
select 'Priyanka' as Name,5 as a 
) 
Update t 
set amount=amount-Aa.a 
from 
    @temp t 
     cross apply 
    (select SUM(a) as a from A where Name = t.Name) Aa 

select * from @temp 

Wo ich die cross apply verwenden, um die Daten auf eine einzige Zeile pro Zielzeile zu aggregieren.


allem aber es macht das Konzept unterstützen, die die Auswirkungen einer UPDATE angewendet werden „als ob“ alle Zeilen (und Spalten in ihnen) parallel aktualisiert werden. Also Sie nicht bekommen, dass zuerst das Update gilt mit einer Zeile und dann das zweite Update bekommt eine bereits aktualisierte Zeile zu aktualisieren.

+0

Aber Sir, wenn wir von XML lesen und die Tabelle aktualisieren, dann kein Problem. –

+0

Ich bin ein bisschen verwirrt. Kannst du mir bitte einen Hinweis geben von wo ich dieses Konzept verstehen kann. –

0

Sie müssen die Werte der Gewerkeinträge SUMMEN. Einfach UNION die Einträge haben mehrere Einträge, so kann es einen Eintrag nehmen und die Überreste ignorieren.

Für Ihren Fall die folgende Abfrage funktioniert:

DECLARE @temp TABLE (NAME VARCHAR(50), amount INT) 

INSERT @temp 
VALUES ('Priyanka', 10) 

UPDATE t 
SET amount = t.amount - A.a 
FROM @temp t 
JOIN (
    SELECT NAME, SUM(a) AS a FROM (
     SELECT 'Priyanka' AS NAME, 1 AS a 
     UNION 
     SELECT 'Priyanka' AS NAME, 5 AS a 
     ) c 
    GROUP BY NAME 
    ) A ON A.NAME = t.NAME 

SELECT * FROM @temp 
+0

Aber Sir, wenn wir von XML statt Select lesen dann funktioniert es gut für mich. –

Verwandte Themen