2016-11-21 6 views
0

Sah ein Kollege eine Abfrage heute ausführen und ich konnte nicht erklären, warum oder wie es nicht scheitern. Die Abfrage wurde (abstrahiert):Warum wird eine Abfrage mit einem ungültigen Subselect ausgeführt?

UPDATE table1 
SET columnToUpdate = 1 
WHERE recordID IN (
SELECT recordID FROM table2 WHERE table2column IN (*list of values*)) 

Das Problem war, er irrt recordID hatte, die nur in table1 ist, für personID, die in beiden Tabellen vorhanden ist, und ist eine PK in Tabelle 1, FK in Tabelle 2.

Ich hätte gedacht, die Abfrage würde nicht ausgeführt werden, da der Subselect nicht aufgelöst werden kann (tatsächlich, wenn Sie den Subselect allein ausführen, schlägt es fehl). Stattdessen führte das Ausführen der obigen Abfrage alle Datensätze in Tabelle1, die zuvor eine Kombination aus NULL und 0 waren, aus.

Es war einfach zu beheben, aber kann jemand erklären, warum dieses Verhalten stattfinden würde?

Danke!

+1

verwendet wird, was Sie meinen, innerer Auserwählter scheitern? Sie meinen, Ihnen einen Fehler geben oder Null zurückgeben? –

+2

So funktionieren korrelierte Unterabfragen. Sicher ist es einfach zu beheben, aber wenn Sie Ihre Programmiergewohnheiten ändern, um IMMER die Tabelle vor Ihren Spalten anzugeben, werden Sie diese Art von Fehlern stark minimieren. –

Antwort

2

Es heißt Korrelierte Unterabfrage. Es hilft Ihnen, äußere Abfrage Spalten innerhalb der Unterabfrage

Die recordID Spalte von table1 in der Unterabfrage nicht aus dem table2 bezeichnet zu verweisen, ist, warum es fehlschlägt, wenn Sie die Unterabfrage allein laufen. Normalerweise können Sie äußere Abfragespalten sehen, die in Where Klausel verwiesen werden, wenn EXISTS/NOT EXISTS

+0

Gute Antwort, und ich kann sehen, warum es jetzt läuft, aber die Folgefrage ist dann- warum hat es jeden Wert in Tabelle1 aktualisiert? Ist in der Auswahl im Wesentlichen ein kartesisches Produkt von allem in Tabelle1 gegen nichts in Tabelle2 zu produzieren gegen zu prüfen? (dh alle von Tabelle1) – David

+1

Es aktualisiert alle Datensätze, denn wenn alle Zeilen in Tabelle2 ausgewählt sind, dann haben Sie Table1.RecordId als Einzelwert in diesen Zeilen ausgewählt - daher ist Table1.RecordId IN (Table1.RecordId) true, falls Zeilen vorhanden überhaupt sind ausgewählt – Cato

3

aus diesen Gründen immer alias Ihre Tabellen und verwenden Sie den Alias ​​im Feldnamen, sonst kann ein einfacher Fehler SQL (richtig) interpretieren das Feld als aus einer anderen Tabelle als die beabsichtigte - die Recordid in Ihre Abfrage ist die aus Tabelle1, wenn sie nicht in Tabelle2 enthalten ist.

UPDATE table1 t1 
SET t1.columnToUpdate = 1 
    WHERE t1.recordID IN (
    SELECT t2.recordID FROM table2 t2 WHERE t2.table2column IN (*list of values*)) 
Verwandte Themen