SQL如何在where子句中处理(或不处理)错误?

时间:2016-06-01 11:14:20

标签: sql sql-server

我意外删除了MULTIPLECALCCLASSDEF表中的所有行,其中包含以下内容:

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

最初看起来很好。问题似乎是SCHEMEHISTID表中没有SCHEME,但是这就是为什么where子句没有返回错误,或者没有行?< / p>

此错误(无效的列名称SCHEMEHISTID):

select SCHEMEHISTID from SCHEME where SCHEMEID = @intScheme

但这并不是:

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

3 个答案:

答案 0 :(得分: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匹配,那么in的任何非NULL值都可以轻松满足SCHEMEHISTID

简单解决方案:始终使用合格的列名称。

答案 1 :(得分:2)

这是因为您在外部查询中添加的列可用于您的子查询,即。,在您的表MULTIPLECALCCLASSDEF中。如果您将其命名为其他名称,例如MULTIPLETEST并尝试则会导致错误。这就是为什么建议在使用此类查询时使用别名和列名。

所以它应该像

/jrs-rest-java-client

答案 2 :(得分:0)

正如Rahul所说,SCHEMEHISTID列包含在MULTIPLECALCCLASSDEF表中。您可以通过执行以下查询轻松检查:

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

VS

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

最后一个应该引发错误。

另一种解决方案是使用系统目录视图:

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'