关于变量@s=@s+name的奇怪现象,大家一起分析~~~

lzhs 2010-09-04 08:46:56
今天仔细研究了下面两个帖子里的变量累加赋值问题,忽然发现一个更加奇怪的现象!
第一个:
http://topic.csdn.net/u/20100903/16/da7e7943-74fd-48c7-a177-e9202906af85.html?seed=1296377010&r=68161348#r_68161348
第二个:
http://topic.csdn.net/u/20091011/18/37fcf166-8abe-47bf-a13d-498fa8c41515.html

具体的请看下面的代码:

DECLARE @TB TABLE (id INT,name varchar(10))
INSERT @TB
SELECT 1 ,'jack' UNION ALL
SELECT 2 ,'sam' UNION ALL
SELECT 6 ,'micle' UNION ALL
SELECT 7 ,'Jop' UNION ALL
SELECT 7 ,'Jop' UNION ALL
SELECT 12, 'Nill'


DECLARE @s1 varchar(10),@s2 varchar(20)


--SQL 1
SELECT @s1='10_'
SELECT @s1=@s1+NAME
FROM
(
SELECT TOP 2 id,name FROM @TB ORDER BY ID
) a
ORDER BY ID DESC
SELECT @s1

--SQL 2(此处语句和1中一样,只是变量@s2的长度比@s1大,结果就完全不一样了)
SELECT @s2='20_'
SELECT @s2=@s2+NAME
FROM
(
SELECT TOP 2 id,name FROM @TB ORDER BY ID
) a
ORDER BY ID DESC
SELECT @s2

--SQL 3(如果把两个变量放在一起,那么结果就一样了)
SELECT @s1='10_',@s2='20_'
SELECT @s1=@s1+NAME,@s2=@s2+NAME
FROM
(
SELECT TOP 2 id,name FROM @TB ORDER BY ID
) a
ORDER BY ID DESC
SELECT @s1,@s2


大家有意见的继续发表发表~~~~~~~~~
...全文
339 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
lzhs 2010-09-07
  • 打赏
  • 举报
回复
结贴了。
《技术内幕-P452页》说了,可能无法确定结果。。。
xiaoku 2010-09-06
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 lzhs 的回复:]
如果多一些这样的分析,对我们更深入的了解底层有很大帮助。
只是想分析一下而己,并不需要最准确的答案。。。。。。
[/Quote]

同意,能够通过分析一些特别的现象,这样有助于理解 底层的实现!
3,肯定是一样的,因为他们的执行顺序都是一样的。
huanghe63 2010-09-06
  • 打赏
  • 举报
回复

DECLARE @TB TABLE (id INT,name varchar(10))
INSERT @TB
SELECT 1 ,'jack' UNION ALL
SELECT 2 ,'sam' UNION ALL
SELECT 6 ,'micle' UNION ALL
SELECT 7 ,'Jop' UNION ALL
SELECT 7 ,'Jop' UNION ALL
SELECT 12, 'Nill'


DECLARE @s1 varchar(10),@s2 varchar(20)


--SQL 1
SELECT @s1='10_'

SELECT @s1=@s1+NAME
FROM
(
SELECT TOP 2 id,name FROM @TB ORDER BY ID
) a
ORDER BY ID DESC

(所影响的行数为 2 行)

StmtText
------------------------------------------------------------------------
|--Sort(ORDER BY:(@TB.[id] DESC))
|--Compute Scalar(DEFINE:([Expr1002]=Convert([@s1]+@TB.[name])))
|--Sort(TOP 2, ORDER BY:(@TB.[id] ASC))
|--Table Scan(OBJECT:(@TB))



StmtText
-------------------------------------------------------------

SELECT @s1



SELECT @s2=@s2+NAME
FROM
(
SELECT TOP 2 id,name FROM @TB ORDER BY ID
) a
ORDER BY ID DESC

(所影响的行数为 2 行)

StmtText
-------------------------------------------------------------------
|--Compute Scalar(DEFINE:([Expr1002]=Convert([@s2]+@TB.[name])))
|--Sort(ORDER BY:(@TB.[id] DESC))
|--Sort(TOP 2, ORDER BY:(@TB.[id] ASC))
|--Table Scan(OBJECT:(@TB))



SELECT @s1='10_',@s2='20_'

SELECT @s1=@s1+NAME,@s2=@s2+NAME
FROM
(
SELECT TOP 2 id,name FROM @TB ORDER BY ID
) a
ORDER BY ID DESC



StmtText
---------------------------------------------------------------------------------------------------------
|--Compute Scalar(DEFINE:([Expr1002]=Convert([@s1]+@TB.[name]), [Expr1003]=Convert([@s2]+@TB.[name])))
|--Sort(ORDER BY:(@TB.[id] DESC))
|--Sort(TOP 2, ORDER BY:(@TB.[id] ASC))
|--Table Scan(OBJECT:(@TB))

这是SQL2000开发版有SP4的执行计划,计算标量之后再默认按标量排序,所以出现了只有最后一条的数据,
还有是SQL2000 企业版 (有/无SP4)的执行计划都是一样的,与上面刚好相反,是排序之后再进行标量计算,可能是版本问题,引起执行计划不同造成的,最好是以执行计划为准,!!!

xingjibing 2010-09-06
  • 打赏
  • 举报
回复
关注中
juyamei126 2010-09-06
  • 打赏
  • 举报
回复
纠结中.....
发现如果 order by 后面同时加 desc或同时不加的话 结果都是理想中的 但是如果其中有一个不加的话就会出现奇怪的现象
DECLARE @s1 varchar(10)
SELECT @s1='10_'
SELECT @s1=@s1+NAME
FROM
(
SELECT TOP 2 id,name FROM @TB ORDER BY ID DESC
) a
ORDER BY ID DESC
SELECT @s1
Mark杨 2010-09-05
  • 打赏
  • 举报
回复

SELECT @s1='10_'
SELECT @s1=@s1+NAME
FROM
(
SELECT TOP 2 id,name FROM @TB ORDER BY ID
) a
SELECT @s1

/*
@s1 中 把查询语句 最后面的排序去掉的话 就全部显示了 只是顺序不对
为什么呢?? 排序就显示不全,不排序就全部显示
*/
lzhs 2010-09-05
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 sqlcenter 的回复:]
纠结这些问题没有太大的意义,了解即可。我看了一下其它两个贴子,所谓的解释都是猜想。

总结一下执行计划:计算标量之后再排序,肯定不是预期的结果
我不会试图解释这种结果,因为我不知道MS的底层实现。

楼主的问题是:变量的长度影响了执行计划。
知道有存在这种可能性即可,要知道为什么,那就看看查询优化器的源代码了。
[/Quote]

如果多一些这样的分析,对我们更深入的了解底层有很大帮助。
只是想分析一下而己,并不需要最准确的答案。。。。。。
Rotel-刘志东 2010-09-05
  • 打赏
  • 举报
回复
正在实践中。
lzhs 2010-09-05
  • 打赏
  • 举报
回复
是的,为什么变量长度不一样,结果就不一样了呢?
这才是我要研究的现象。
SQLCenter 2010-09-05
  • 打赏
  • 举报
回复
纠结这些问题没有太大的意义,了解即可。我看了一下其它两个贴子,所谓的解释都是猜想。

总结一下执行计划:计算标量之后再排序,肯定不是预期的结果
我不会试图解释这种结果,因为我不知道MS的底层实现。

楼主的问题是:变量的长度影响了执行计划。
知道有存在这种可能性即可,要知道为什么,那就看看查询优化器的源代码了。
就是just4 2010-09-04
  • 打赏
  • 举报
回复
楼主这问题也真是奇怪了,楼楼上似乎并不是楼主想问的吧

直接改@s1的长度为12就行了,长度短了还有这问题,!

DECLARE @s1 varchar(12)

--SQL 1
SELECT @s1='10_'

SELECT @s1 = @s1 + name
FROM
(
SELECT TOP 2 id,name FROM @TB ORDER BY ID
) a
ORDER BY ID DESC
SELECT @s1
SELECT LEN(@s1)

「已注销」 2010-09-04
  • 打赏
  • 举报
回复
要是你明白下面这个动态Sql的原理你就明白你上面的现象了。
你可以加上Print @s1,与Print @s2就明白了。
其实也挺好理解的。

create table tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int)
insert into tb values('张三' , '语文' , 74)
insert into tb values('张三' , '数学' , 83)
insert into tb values('张三' , '物理' , 93)
insert into tb values('李四' , '语文' , 74)
insert into tb values('李四' , '数学' , 84)
insert into tb values('李四' , '物理' , 94)
go

--SQL SERVER 2000 动态SQL,指课程不止语文、数学、物理这三门课程。(以下同)
declare @sql varchar(8000)
set @sql = 'select 姓名 '
select @sql = @sql + ' , max(case 课程 when ''' + 课程 + ''' then 分数 else 0 end) [' + 课程 + ']'
from (select distinct 课程 from tb) as a
set @sql = @sql + ' from tb group by 姓名'
exec(@sql)

jason69181 2010-09-04
  • 打赏
  • 举报
回复
@s 这样的我学的时候当成变量. 这样的话,里面就可以放值了

不知道你想说的是什么!

22,206

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧