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 语句,并且几乎在第一时间就让它们工作了。
干杯
我什至想不出这个标题怎么写。这是 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 语句,并且几乎在第一时间就让它们工作了。
干杯