我甚至无法想到如何说出这个标题。这是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;
这个查询我直接把所有东西都假装到了表中,并得到了相当大的回报。
非常相似的查询,但我没有指定表
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;
第二个查询返回1.
此之间的仅相互列是B-ForeignKey => M.PrimaryKey
根据我的经验,我总是将列分配给别名,但是当有人早些时候问我上述问题时,我发现自己很困惑。如果它们含糊不清,SSMS会拒绝它。但是,它实际上已经运行了。
所以我想也许'它忽略了那些列 - 这很奇怪。 但是第二次返回-1-行,这增加了更多的混乱。
有人能解释为什么别名与非别名查询会发生变化吗?如果它出现错误,它为什么会完成?
答案 0 :(得分:1)
根据我的经验,我从不直接通过数据库名称来引用表。我总是 Alias ,因为它更易于阅读,并且在相同的精确列名和数据类型跨越两个或更多的情况下,我也明确指出了哪些列表。
尝试这一点并坚持使用相同的设计,你将始终得到你期望的结果:
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;
AS反对......
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可能会在两个表之间混淆,如果两个表有一个或多个相同的列定义。实际上它可能甚至不会运行错误!因此,为什么使用别名,我知道我指的是什么表,它只更新我想要的列和表。
这是一个提示:
将UPDATE视为"壶壶盖",其中锅的优点"" (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
一样。而且您不必更新查询中的第一个表。您可以更新b或UPDATE c等,而不会影响查询的FROM子句中的逻辑。
所以我的建议是编写一个SELECT查询来获取您想要的数据,使其工作,然后将SELECT替换为UPDATE & SET
,具体取决于您要更改的列。这样我就不会对我正在改变的数据感到困惑。
我设法以这种方式创建大量的UPDATE SQL语句,并使它们几乎第一次工作。
干杯
答案 1 :(得分:0)
如果任何列引用含糊不清,则会出现错误。这些查询对我来说看起来是一样的,但谓词Col1 > 0
可能会在每次执行后过滤掉不同的行,因为你要减少它们。另外,我假设B.M-FK
是你混淆的工件,因为它被解释为B.M - B.FK
。我假设您的意思是B.[M-FK]
或B.M_FK
。
我也看到(NOLOCK)
。如果数据在B
中变化,可能会有所贡献。