Mar*_*las 3 sql database theory sql-server-2005
假设您在表上运行UPDATE语句,但是您在此基表中放入的信息来自其他一些辅助表.通常,您将加入数据并且不期望UPDATE语句的FROM子句中的行相乘,从而保持一个新行映射到基表中的一个旧行.
但是我想知道如果你的JOIN表在某种程度上是模棱两可的会发生什么,就像你无法将每个基本实体映射到一个连接的实体一样.或者,如果你做了一些荒谬的事情,比如将基表连接到其子表,并使用该信息更新基表.它会如何选择?现在每个基表行有多行.
我在SQL Server 2005中运行了这样的语句,它似乎是在每个集合中选择第一行.但这对我来说似乎不对.不应该发错吗?为什么这是理想的行为?
示例代码
-- normal
-- categories are one-to-many bundles
update bundles_denormalized set category = c.description
from bundles_denormalized b
left join categories c
on b.category_id = c.id
-- ambiguous
-- bundles are one-to-many products
update bundles_denormalized set category = p.description
from bundles_denormalized b
left join products p
on b.id = p.bundle_id
Run Code Online (Sandbox Code Playgroud)
实际上,如果我正确地理解了这个问题,它会多次更新该字段,那只是因为只有一条记录,所以最终只有一个值.为什么不出错?因为语法是正确的,并且数据库无法知道您的意图是什么.你想这样做吗?通常情况下,这就是为什么您应该在运行之前选择更新以确保更正记录获得正确的值.
我通常用这种方式写一个更新加入:
update b
set category = p.description
--select b.category, p.description
from bundles_denormalized b
left join products p on b.id = p.bundle_id
Run Code Online (Sandbox Code Playgroud)
我也会警惕在更新中使用左连接,因为您可能会将值更改为空值.如果这是你想要的,那就没关系,但如果不是,那就没关系.
将 UPDATE 与 FROM 子句一起使用
如果 UPDATE 语句包含的 FROM 子句未指定为每个更新的列出现只有一个值,即 UPDATE 语句不是确定性的,则该语句的结果是未定义的。例如,在下面脚本的UPDATE语句中,Table1中的两行都满足UPDATE语句中FROM子句的条件;但未定义 Table1 中的哪一行用于更新 Table2 中的行。
Run Code Online (Sandbox Code Playgroud)USE AdventureWorks; GO IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL DROP TABLE dbo.Table1; GO IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL DROP TABLE dbo.Table2; GO CREATE TABLE dbo.Table1 (ColA int NOT NULL, ColB decimal(10,3) NOT NULL); GO CREATE TABLE dbo.Table2 (ColA int PRIMARY KEY NOT NULL, ColB decimal(10,3) NOT NULL); GO INSERT INTO dbo.Table1 VALUES(1, 10.0); INSERT INTO dbo.Table1 VALUES(1, 20.0); INSERT INTO dbo.Table2 VALUES(1, 0.0); GO UPDATE dbo.Table2 SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB FROM dbo.Table2 INNER JOIN dbo.Table1 ON (dbo.Table2.ColA = dbo.Table1.ColA); GO SELECT ColA, ColB FROM dbo.Table2;
换句话说,它是一种有效的语法,不会抛出错误或异常。
但同时您不能确定更新值将是您的 FROM 子句中的第一个或最后一个记录,因为它没有定义。