日期:2014-05-18 浏览次数:20526 次
--1.请大家分别在2000与2005中运行,看看#t1表中的fQty的值是多少 --2.为什么会有这种差别呢 create table #t1(fCode varchar(10),fQty int) create table #t2(fCode varchar(10),fQty int) insert into #t1(fCode,fQty) select 'A',0 insert into #t2(fCode,fQty) select 'A',5 union all select 'A',4 union all select 'A',8 union all select 'A',1 union all select 'A',3 update a set a.fQty=b.fQty from #t1 a join #t2 b on a.fCode=b.fCode select * from #t1
create table #t1(fCode varchar(10),fQty int) create table #t2(fCode varchar(10),fQty int) insert into #t1(fCode,fQty) select 'A',0 insert into #t2(fCode,fQty) select 'A',5 union all select 'A',4 union all select 'A',8 union all select 'A',1 union all select 'A',3 update a set a.fQty=b.fQty from #t1 a join #t2 b on a.fCode=b.fCode select * from #t1 /* fCode fQty ---------- ----------- A 5 */ drop table #t1 drop table #t2 /* Microsoft SQL Server 2005 - 9.00.1399.06 (Intel X86) */
------解决方案--------------------
这样子更新是确定不了什么的,2000和2005的排序规则可能有异同的地方,而且更新的是多对一,本身是不确定的。没什么意义。
------解决方案--------------------
1表对应b表的多条记录,这样更新没什么意义,排序不一样,结果就不一样
------解决方案--------------------
--2000的运行结果如下 fCode fQty ---------- ----------- A 3 --分析::a的fCode和b的五个fCode都匹配, --但更新时是按顺序取最后一个,类似select @a=name from tb,结果@a肯定是tb表的最后一个name
------解决方案--------------------
SQL的执行顺序 从左到右,依次更新,变量优先
------解决方案--------------------
用UPDATE的方式更新数据本身就有不确定性,看一下计划就知道了
IF OBJECT_ID('TEMPDB..#T1') IS NOT NULL DROP TABLE #T1 IF OBJECT_ID('TEMPDB..#T2') IS NOT NULL DROP TABLE #T2 GO create table #t1(fCode varchar(10),fQty int) create table #t2(fCode varchar(10),fQty int) insert into #t1(fCode,fQty) select 'A',0 insert into #t2(fCode,fQty) select 'A',5 union all select 'A',4 union all select 'A',8 union all select 'A',1 union all select 'A',3 GO SET SHOWPLAN_TEXT ON GO update a set a.fQty=b.fQty from #t1 a join #t2 b on a.fCode=b.fCode GO SET SHOWPLAN_TEXT OFF GO /* |--Table Update(OBJECT:([tempdb].[dbo].[#t1] AS [a]), SET:([tempdb].[dbo].[#t1].[fQty] as [a].[fQty] = [tempdb].[dbo].[#t2].[fQty] as [b].[fQty])) |--Top(ROWCOUNT est 0) |--Stream Aggregate(GROUP BY:([Bmk1000]) DEFINE:([b].[fQty]=ANY([tempdb].[dbo].[#t2].[fQty] as [b].[fQty]))) |--Nested Loops(Inner Join, WHERE:([tempdb].[dbo].[#t2].[fCode] as [b].[fCode]=[tempdb].[dbo].[#t1].[fCode] as [a].[fCode])) |--Table Scan(OBJECT:([tempdb].[dbo].[#t1] AS [a])) |--Table Scan(OBJECT:([tempdb].[dbo].[#t2] AS [b])) */
------解决方案--------------------
等同於
update Top (1) a set FQty=b.FQty from #t1 a join #t2 b on a.fCode=b.fCode
------解决方案--------------------
两个表没有聚集索引,是堆结构,也就是说数据在堆中的顺序是随机的,所以数据被访问的顺序也是随机的。跟2000和2005没关系。你找两台sql server 2000,也可能产生不一样的结果,数据量大的时候更容易重现这种现象。
------解决方案--------------------