SSMS 2005 - Non-aliased 列返回不同的结果

SSMS 2005 - Non-aliased column returning different results

我什至想不出这个标题怎么写。这是 SQL Server 2005

如果我在列上使用别名执行相同的查询,与不使用别名相比,我会得到完全不同的结果。这不是模棱两可的。

示例查询:

    UPDATE  MyTable
SET     Col1 = Col1 - 1
FROM    DB.dbo.MyTable M
WHERE   EXISTS ( SELECT *
                 FROM   DB.dbo.SecondTable B WITH ( NOLOCK )
                 WHERE  B.Col2 = 12345678
                        AND B.Col3 = 1
                        AND B.M-FK = M.M-PK )
        AND M.Col1 > 0
        AND M.Col4 = 87654321;

这个查询我直接把所有东西都假设给了 table,我得到了一个相当大的 return.

非常相似的查询,但我没有指定 table

UPDATE  MyTable
SET     Col1 = Col1 - 1
FROM    DB.dbo.MyTable M
WHERE   EXISTS ( SELECT *
                 FROM   DB.dbo.SecondTable B WITH ( NOLOCK )
                 WHERE  Col2 = 12345678
                        AND Col3 = 1
                        AND B.M-FK = M.M-PK )
        AND Col1 > 0
        AND Col4 = 87654321;

第二个查询returns 1.

这之间的只有相互的列是B-ForeignKey=>M.PrimaryKey

根据我的经验,我总是将列分配给一个别名,但是当之前有人问我上述问题时,我发现自己很困惑。如果它们不明确,SSMS 将拒绝它。然而,它实际上 运行.

所以我认为 'maybe' 它忽略了那些列 - 这很奇怪。 但是第 2 returns -1- 行,这增加了更多的混乱。

谁能准确解释为什么别名与 non-alias 查询会发生变化?如果是错误,为什么它会完成?

如果任何列引用不明确,您将收到错误消息。这些查询对我来说看起来是一样的,但是谓词 Col1 > 0 可能会在每次执行后过滤掉不同的行,因为您正在递减它。另外,我假设 B.M-FK 是你混淆的产物,因为它会被解释为 B.M - B.FK。我假设你的意思是 B.[M-FK]B.M_FK.

我也看到了(NOLOCK)。如果数据在 B 中不断变化,那可能会有所贡献。

根据我的经验,我从不直接通过数据库名称引用 table。我总是 Alias 它们,因为它更容易阅读,并且在两个或多个相同的确切列名和数据类型的情况下,我也很清楚我指的是什么列 tables.

试试这个,并坚持使用相同的设计,您将始终获得预期的结果:

UPDATE  m
SET     m.Col1 = m.Col1 - 1
FROM    dbo.MyTable AS m
WHERE   EXISTS ( SELECT *
                 FROM   dbo.SecondTable AS b WITH ( NOLOCK )
                 WHERE  b.Col2 = 12345678
                        AND b.Col3 = 1
                        AND b.M-FK = m.M-PK )
        AND m.Col1 > 0
        AND m.Col4 = 87654321;

反对...

UPDATE  dbo.MyTable
SET     Col1 = Col1 - 1
WHERE   EXISTS ( SELECT *
                 FROM   dbo.SecondTable AS b WITH ( NOLOCK )
                 WHERE  b.Col2 = 12345678
                        AND b.Col3 = 1
                        AND b.M-FK = M-PK )
        AND Col1 > 0
        AND Col4 = 87654321;

第二个版本的问题是 SQL 可能会混淆两个 table,如果两个 table 有一个或多个 相同的列定义。 事实上,由于这些错误,它甚至可能 运行!因此,为什么使用别名,我知道 table 我指的是什么,它只更新列和我想要的 table。

这里有一个提示:

将 UPDATE 视为 "kettle pot cover",其中优点 "of the pot"(SELECT 语句)就在锅里!

即:

UPDATE a
SET a.col1 = @value1, a.col2 = @value2, etc
FROM dbo.myTable1 AS a
  INNER JOIN dbo.myTable2 as b ON b.col3 = a.col3
  INNER JOIN ...etc..
WHERE ..etc..

请注意,从 FROM 子句来看,它就像一个 SELECT。而且您不必更新查询中的第一个 table。您可以 UPDATE b 或 UPDATE c 等,而不会影响查询的 FROM 子句中的逻辑。

所以我的建议是编写一个 SELECT 查询以首先获取您想要的数据,使其正常工作,然后根据您使用的列将 SELECT 替换为 UPDATE & SET想改变。这样我就不会对正在更改的数据感到困惑。

我已经设法通过这种方式创建了大量的 UPDATE SQL 语句,并且几乎在第一时间就让它们工作了。

干杯