2016-06-01 7 views
2

私は誤って次でMULTIPLECALCCLASSDEFテーブル内のすべての行を削除:最初は細かい見えたSQLはwhere句内のエラーをどのように処理(または処理しない)しますか?

delete 
from MULTIPLECALCCLASSDEF 
where SCHEMEHISTID in (select SCHEMEHISTID from SCHEME where SCHEMEID = @intScheme) 

。問題は、SCHEMEテーブルにSCHEMEHISTIDが存在しないように見えますが、これが原因でwhere句がエラーを返さないのはなぜですか。

このエラー(無効な列名のSCHEMEHISTID):

select SCHEMEHISTID from SCHEME where SCHEMEID = @intScheme 

しかし、これはしていません:

select * 
from MULTIPLECALCCLASSDEF 
where SCHEMEHISTID in (select SCHEMEHISTID from SCHEME where SCHEMEID = @intScheme) 
+3

をしているので、常にa.qualifierを使用してgreat.ideaであることを知っています –

答えて

3

ようにする必要があり、あなたは表の別名と(表別名を含む)修飾列名を使用する必要があります。これは、相関サブクエリを使用している場合に特に当てはまります。そして、あなたはただの理由を知りました。あなたが意図した

問い合わせは:

delete c 
    from MULTIPLECALCCLASSDEF c 
    where c.SCHEMEHISTID in (select s.SCHEMEHISTID from SCHEME s where s.SCHEMEID = @intScheme); 

これは、エラーが発生しているだろう。エイリアスなし

は、クエリは次のように解釈される:

delete c 
    from MULTIPLECALCCLASSDEF c 
    where c.SCHEMEHISTID in (select c.SCHEMEHISTID from SCHEME s where s.SCHEMEID = @intScheme); 

さて、whereへの一致があると仮定すると、次にinSCHEMEHISTIDための任意の非NULL値によって自明に満たされます。

単純な解決方法:修飾された列名を常に使用してください。

2

そのあなたが外側のクエリに追加した列があなたのサブクエリに利用可能であるため、つまり、あなたのテーブルMULTIPLECALCCLASSDEFにあります。たとえばMULTIPLETESTのような別の名前を付けて試してみるとエラーになります。このようなクエリを使用しているときに、エイリアス名とカラム名を併用することをお勧めします。

だから、それは一般的に

delete 
    from MULTIPLECALCCLASSDEF 
    where SCHEMEHISTID in (select MULTIPLECALCCLASSDEF.SCHEMEHISTID from SCHEME where SCHEMEID = @intScheme); 
0

ラフルが述べたように、SCHEMEHISTID欄はMULTIPLECALCCLASSDEFに含まれています。あなたは以下のクエリを実行することで簡単に確認できます。

select * 
from MULTIPLECALCCLASSDEF AS h 
where h.SCHEMEHISTID in (select h.SCHEMEHISTID from SCHEME AS s where s.SCHEMEID = @intScheme) 

select * 
from MULTIPLECALCCLASSDEF AS h 
where h.SCHEMEHISTID in (select s.SCHEMEHISTID from SCHEME AS s where s.SCHEMEID = @intScheme) 

エラーを発生させる必要があり、最後の1。

別の解決策は、システム・カタログ・ビューを使用することです:

SELECT s.name, t.name, c.name 
FROM sys.schemas s 
JOIN sys.tables t ON s.schema_id = t.schema_id 
JOIN sys.columns c ON c.object_id = t.object_id 
WHERE s.name = N'dbo' 
AND t.name IN (N'MULTIPLECALCCLASSDEF', N'SCHEME') 
AND c.name = N'SCHEMEHISTID' 
関連する問題