2017-01-13 6 views
0

Ich habe einen allgemeinen Tabellenausdruck, den ich benutze, um zu versuchen, als Update-Anweisung zu verwenden. Der einzige Grund für den CTE ist, dass ich eine Where-Klausel verwenden kann, um nach CredCount zu filtern. Ich möchte diese Where-Klausel verwenden, um nur Datensätze zu aktualisieren, die in diesem Fall CredCount von 2 entsprechen. Ich habe jedoch Probleme mit dem Update-Teil der Abfrage.Update-Anweisung SQL mit CTE

+---------------+--------------+-----------+-----------------+ 
| Members_id | Credentials | CredCount |members_amountdue| 
+---------------+--------------+-----------+-----------------+ 
| 1    | CMA, CPR  |  2 | 0   | 
| 2    | CMA, CPR  |  2 | 0   | 
| 3    | CMA, CPR  |  2 | 0   | 
+---------------+--------------+-----------+-----------------+ 

ist die Abfrage für diese

WITH CTE AS (
SELECT members_id, members_amountdue, [Credentials], LEN([Credentials]) - LEN(REPLACE([Credentials], ',', '')) + 1 AS CredCount 
FROM (
     SELECT DISTINCT mem1.members_id, mem1.members_amountdue, 
      STUFF(
       (SELECT DISTINCT ', ' + credentials_code 
       FROM members AS mem JOIN 
       members_credentials AS mc ON mc.members_id = mem.members_id JOIN 
       credentials AS c ON c.credentials_id = mc.credentials_id 
       WHERE mem.[members_id] = mem1.[members_id]    
       FOR XML PATH ('')), 1, 1, '') AS [Credentials] 
     FROM members AS mem1 JOIN 
     members_status as ms on ms.members_status_id = mem1.members_status_id 
    ) AS derived), 
CTE2 AS (SELECT members_id 
      FROM members) 
SELECT CTE.members_id, CTE.Credentials, CTE.CredCount, (CTE.members_amountdue + 25) as NewPriceTotal 
FROM CTE JOIN 
CTE2 ON CTE.members_id = CTE2.members_id 
WHERE CTE.CredCount = 2 

Mit der Update-Anweisung Ich war an einem Beispiel der Suche zur Verfügung gestellt hier bei Update records in table from CTE so fügte ich die Update-Anweisung auf die Unterseite der Abfrage

WITH CTE AS (
SELECT members_id, members_amountdue, [Credentials], LEN([Credentials]) - LEN(REPLACE([Credentials], ',', '')) + 1 AS CredCount 
FROM (
     SELECT DISTINCT mem1.members_id, mem1.members_amountdue, 
      STUFF(
       (SELECT DISTINCT ', ' + credentials_code 
       FROM members AS mem JOIN 
       members_credentials AS mc ON mc.members_id = mem.members_id JOIN 
       credentials AS c ON c.credentials_id = mc.credentials_id 
       WHERE mem.[members_id] = mem1.[members_id]    
       FOR XML PATH ('')), 1, 1, '') AS [Credentials] 
     FROM members AS mem1 JOIN 
     members_status as ms on ms.members_status_id = mem1.members_status_id 
    ) AS derived), 
CTE2 AS (SELECT members_id 
      FROM members) 
SELECT CTE.members_id, CTE.Credentials, CTE.CredCount, (CTE.members_amountdue + 25) as NewPriceTotal 
FROM CTE JOIN 
CTE2 ON CTE.members_id = CTE2.members_id 
WHERE CTE.CredCount = 2 
UPDATE members 
set members_amountdue = NewPriceTotal 

Wenn ich die Update-Anweisung hinzufügen, erhalte ich einen Fehler für den ungültigen Spaltennamen für 'NewPriceTotal'. Ich weiß, dass die Spalte übereinstimmen muss, damit das Update funktioniert, aber ich bin mir nicht sicher, warum es ungültig ist.

+---------------+--------------+-----------+----------------+ 
| Members_id | Credentials | CredCount | NewPriceTotal | 
+---------------+--------------+-----------+----------------+ 
| 1    | CMA, CPR  |  2 | 25   | 
| 2    | CMA, CPR  |  2 | 25   | 
| 3    | CMA, CPR  |  2 | 25   | 
+---------------+--------------+-----------+----------------+ 

ich für die NewPriceTotal möchte am members_amountdue aus der Mitglieder-Tabelle gesetzt werden, aber ich bin mir nicht sicher, wo ich den falschen Weg eingeschlagen hat. Jede Hilfe, Kommentare oder Feedback wird sehr geschätzt.

+3

Das Update ist eine gesonderte Erklärung, und hat keine Ahnung, alles, was man mit CTEs tat. CTEs sind wie temporäre Inline-Ansichten und werden nicht beibehalten. Vielleicht sollten Sie die Ausgabe in eine #temp-Tabelle ausgeben und Ihre UPDATE-Anweisung ändern, um sie der Tabelle #temp hinzuzufügen. –

Antwort

1

Versuchen Sie folgendes:

.... 
CTE2 AS ( 
    SELECT members_id 
    FROM members 
), CTE3 AS (
    SELECT CTE.members_id, CTE.Credentials, CTE.CredCount, 
      CTE.members_amountdue, 
      (CTE.members_amountdue + 25) as NewPriceTotal 
    FROM CTE JOIN CTE2 ON CTE.members_id = CTE2.members_id 
    WHERE CTE.CredCount = 2) 
UPDATE CTE3 
SET members_amountdue = NewPriceTotal 
+1

Vielen Dank für Ihren Vorschlag, aber dieser Fehler tritt auf "Msg 4403, Ebene 16, Status 1, Zeile 1 Die Ansicht oder Funktion 'CTE3' kann nicht aktualisiert werden, da sie Aggregate oder eine DISTINCT- oder GROUP BY-Klausel oder PIVOT- oder UNPIVOT-Operator enthält . " – Jay

+1

@Jay ist dies auf das Schlüsselwort 'DISTINCT' zurückzuführen, das im CTE der obersten Ebene verwendet wird. Das "UPDATE" wird an die reale Tabelle in der Datenbank weitergegeben. Die Verwendung von "DISTINCT" macht es der Engine schwer zu bestimmen, welche genaue Zeile zu aktualisieren ist. Was wäre das Ergebnis, wenn du 'DISTINCT' nicht benutzt hättest? –

+0

Danke Giorgos - Ich schätze die Hilfe. Deine Vorschläge waren richtig. – Jay