2017-06-16 2 views
0

Das Problem verweist auf einen Spaltennamen, der nicht innerhalb der Tabellenvariablen innerhalb einer gespeicherten Prozedur liegt. Ich würde annehmen, dass dies zu einem Fehler geführt haben sollte, aber es gibt stattdessen Werte zurück, da der Spaltenname in der Hauptabfrage gefunden wird.TSQL-Problem mit Tabellenvariable mit ungültigen Spaltennamen

Ist das ein bekanntes Problem, vielleicht in SQL Fest 2016? Oder wird dieses Verhalten erwartet?

DECLARE @LookupTable TABLE(MyId Integer, PRIMARY KEY(MyId)); 
INSERT INTO @LookupTable (MyId) Values (1); 


DECLARE @DataTable TABLE(My_Id Integer, MyOtherField Char(1), PRIMARY KEY(My_Id)); 
INSERT INTO @DataTable (My_Id,MyOtherField) Values (1,'A'); 
INSERT INTO @DataTable (My_Id,MyOtherField) Values (2,'B'); 
INSERT INTO @DataTable (My_Id,MyOtherField) Values (3,'C'); 


--SELECT MyId works as expected (one row) 
SELECT MyOtherField FROM @DataTable 
WHERE My_Id IN (SELECT MyId FROM @LookupTable) 

--SELECT My_Id should be an error 
--Returns three rows when referencing a column name not in @LookupTable 
SELECT MyOtherField FROM @DataTable 
WHERE My_Id IN (SELECT My_Id FROM @LookupTable) 

--Returns expected error: invalid column name 'My_Id' 
SELECT My_Id FROM @LookupTable 

SQL Server 2014 (SP2).

+0

Ich habe dieses Verhalten vorher gesehen, in diesem Sinne wird es erwartet ... Wenn Sie die Spalten richtig identifizieren (zB: 'von @DataTable DT wo DT.My_id' usw.), erhalten Sie das logisch erwartete Ergebnis. – HoneyBadger

+1

Dies wird vollständig erwartet. In der Abfrage, die Sie für einen Fehler halten sollten, verwendet die Unterabfrage tatsächlich My_Id von @DataTable, nicht MyId, wie Sie denken. Dies ist ein klassisches Beispiel dafür, warum es so wichtig ist, jede einzelne Spalte mit der Tabelle (oder vorzugsweise dem Alias) zu referenzieren, um dieses Problem zu vermeiden. –

Antwort

2

M_Id Spalte in Teilabfrage wird von äußeren Tabelle @DataTable bezeichnet. Es heißt korrelierte Unterabfrage. Auf die Spalte aus der äußeren Tabelle kann innerhalb der Unterabfrage verwiesen werden.

Jetzt wird es mehr Sinn machen.

SELECT MyOtherField FROM @DataTable T 
WHERE T.My_Id IN (SELECT T.My_Id FROM @LookupTable) 

Meistens wird die korrelierte Unterabfrage verwendet, wenn exists verwendet wird. Sie können die Spalte von äußeren Tabelle in Where Klausel sehen

+0

Natürlich macht es Sinn ... aber wenn man ein größeres Stück betrachtet, durchläuft es eine Schleife. Hatte heute morgen die Scheuklappen zu nehmen ... –

+0

@DarianMiller - Perfekt gültige Frage. Ich habe viele gesehen, die ähnliche Fragen stellen –

1

[1] Weitere Angaben zu dem gemeldeten „Problem“ bezeichnet werden: aktuelle Frage der Auffassung, dass Abfrage folgenden

SELECT MyOtherField FROM @TableA 
WHERE ColumnFromTableA IN (SELECT ColumnFromTableA FROM @TableB) 

unerwartete Ergebnisse.

[2] Dies ist kein Fehler.

[3] Dies ist das erwartete Verhalten: es DBMS nicht findet ColumnFromTableA im lokalen Bereich von @TableB wird es mit Erfolg durchgeführt werden (ohne Warnungen/Ausnahmen), wenn diese Spalte in @TableA existiert (ex SQL Server.).

Verwandte Themen