请务必说明下测试环境,是sql2000,还是2005,或者2008 ? 具体点更好。
原因??
Create table T(id char(10))
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'select '#'+case id when 'C' then '' else id end+'$' from TDrop table T--我测试下的结果
/*
sql2000 sp4 的
------------------------
#A $
#B $
# $sql2005 的结果不同
#A $
#B $
#$ -- 这笔不一样。。*/
原因??
Create table T(id char(10))
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'select '#'+case id when 'C' then '' else id end+'$' from TDrop table T--我测试下的结果
/*
sql2000 sp4 的
------------------------
#A $
#B $
# $sql2005 的结果不同
#A $
#B $
#$ -- 这笔不一样。。*/
解决方案 »
- 请问在ms sql server怎么取表里时间的月份并按月份汇总?
- 英文版的sql2000能存储中文字符串吗?
- 为何instead of触发器不起作用,在线等,TKS
- 急求一条SQL语句,竖向数据变为横向数据,找了好多,发觉都不一样,特请教!
- ■■■■求SQL语句 选择表 月统计 创建视图■■■■
- 执行效率问题,一直没想明白,希望得到皱建等高手指导~~~
- 请教简单问题
- 在用存储过程插入数据的问题。
- =========如何协调两台单机中的数据库的数据更新??????========
- 我用的是2012的数据库,可是附加光盘上的2008数库却附加不上,怎么才能附加上去呀
- 帮我看看这个错误
- 跪求sql2008下载地址!
知道的麻烦解释下。
#B $
# $sql 2000
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'select '#'+case id when 'C' then '' else id end+'$' from TDrop table T--我测试下的结果
/*
sql2000 sp4 的
------------------------
#A $
#B $
# $
*/
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'select '#'+case id when 'C' then '' else id end+'$' from T--Drop table T(所影响的行数为 1 行)
(所影响的行数为 1 行)
(所影响的行数为 1 行)
------------
#A $
#B $
# $(所影响的行数为 3 行)
2000
#B $
#$
sql 2008
version:Microsoft SQL Server 2008 (SP1) - 10.0.2531.0 (Intel X86)
Mar 29 2009 10:27:29
Copyright (c) 1988-2008 Microsoft Corporation
Standard Edition on Windows NT 5.2 <X86> (Build 3790: Service Pack 2)
*/
Create table T(id char(10))
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'select '#'+case id when 'C' then '' else id end+'$' from TDrop table T/*
#A $
#B $
#$
*/
sql2000好像会以那个那位的属性(char(10)) 来定义,
而sql2005不会不知道是sql server的设定问题?
还是sql2005/sql2008 改过的特性?迷茫ing......因为要从sql2000 upgrade to sql2005,碰到这档子事,抓狂。。
#A $
#B $
#$SQL 2005
------------
#A $
#B $
# $(所影响的行数为 3 行)
1.char 与 nchar 结果是一样的
2.表结构修改的可能性不大,不知道为什么当初不用varchar 。
Create table T(id char(10))
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'select '#'+case id when 'C' then '' else id end+'$' from TDrop table T
/*
------------
#A $
#B $
#$(3 個資料列受到影響)
*/
----------------------------------------------------------------
-- Author :fredrickhu(我是小F,向高手学习)
-- Date :2009-10-14 11:51:25
-- Version:
-- Microsoft SQL Server 2005 - 9.00.4035.00 (Intel X86)
-- Nov 24 2008 13:01:59
-- Copyright (c) 1988-2005 Microsoft Corporation
-- Developer Edition on Windows NT 5.2 (Build 3790: Service Pack 1)
--
----------------------------------------------------------------Create table T(id char(10))
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'select '#'+case id when 'C' then '' else id end+'$' from TDrop table T
/*------------
#A $
#B $
#$(3 行受影响)
*/
Create table T(id char(10))
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'select '#'+case id when 'C' then '' else id end+'$' from TDrop table T
------------
#A $
#B $
#$(3 行受影响)
select @@versionMicrosoft SQL Server 2005 - 9.00.1399.06 (Intel X86)
Oct 14 2005 00:33:37
Copyright (c) 1988-2005 Microsoft Corporation
Developer Edition on Windows NT 5.1 (Build 2600: Service Pack 2)
(1 行受影响)
select @@version
Create table T(id char(10))
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'select '#'+case id when 'C' then '' else id end+'$' from TDrop table T
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Microsoft SQL Server 2005 - 9.00.1399.06 (X64)
Oct 14 2005 00:35:21
Copyright (c) 1988-2005 Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 5.2 (Build 3790: Service Pack 2)------------
#A $
#B $
# $
CASE input_expression
WHEN when_expression THEN result_expression
[ ...n ]
[
ELSE else_result_expression
]
END
Searched CASE function:
CASE
WHEN Boolean_expression THEN result_expression
[ ...n ]
[
ELSE else_result_expression
]
END结果类型
从 result_expressions 和可选 else_result_expression 的类型集中返回优先级最高的类型。有关详细信息,请参阅 数据类型优先级 (Transact-SQL)。
当两个不同数据类型的表达式用运算符组合后,数据类型优先级规则指定将优先级较低的数据类型转换为优先级较高的数据类型。如果此转换不是所支持的隐式转换,则返回错误。当两个操作数表达式具有相同的数据类型时,运算的结果便为该数据类型。
SQL Server 对数据类型使用以下优先级顺序:
用户定义数据类型(最高)
sql_varian t
xml
datetimeoffset
datetime2
datetime
smalldatetime
date
time
float
real
decimal
money
smallmoney
bigint
int
smallint
tinyint
bit
ntext
text
image
timestamp
uniqueidentifier
nvarchar(包括 nvarchar(max))
nchar
varchar(包括 varchar(max))
char
varbinary(包括 varbinary(max))
binary(最低)
varchar优先级别比char高#A $
#B $
#$这个结果附合联机文档,而
#A $
#B $
# $
不附合联机文档说法
SQL 2000 SP4测试结果:
#A $
#B $
# $
偶的是2005的Create table T(id char(10))
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'select '#'+case id when 'C' then '' else id end+'$' from TDrop table T
------------
#A $
#B $
#$
Microsoft SQL Server 2005 - 9.00.1399.06 (Intel X86)
Oct 14 2005 00:33:37
Copyright (c) 1988-2005 Microsoft Corporation
Developer Edition on Windows NT 5.1 (Build 2600: Service Pack 3)
(1 行受影响)
#B $
# $Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86) Jul 9 2008 14:43:34 Copyright (c) 1988-2008 Microsoft Corporation Developer Edition on Windows NT 5.1 <X86> (Build 2600: Service Pack 3)
我测试看了下执行计划,2000
第二步是计算那个表达式,''空格会转成与ID类型一致的空格哦,所以结果是那样的
select '#'+case id when 'C' then '' else id end+'$' from T(所影响的行数为 1 行)StmtText
---------------------------------------------------------------------------------------------------
|--Compute Scalar(DEFINE:([Expr1002]='#'+If ([T].[id]='C') then ' ' else [T].[id]+'$'))
|--Table Scan(OBJECT:([lsddb2].[dbo].[T]))(所影响的行数为 2 行)
2005的不清楚哦
------------
#A $
#B $
#$(3 行受影响)
sql 2005
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'
go
SET SHOWPLAN_TEXT Off
goselect cast('#' as char(10))+case id when 'C' then '' else id end+'$' from T Drop table T
/* 2005
---------------------
# A $
# B $
# $(3 行受影响)
*/
insert into T select 'A'
insert into T select 'B'
insert into T select 'C' select '#'+case id when 'C' then '' else id end+'$' from T Drop table T --我测试下的结果
/*
sql2000 sp3 的
------------------------
#A $
#B $
# $
*/
#A $
#B $
# $(所影响的行数为 3 行)sql2000 sp4
SELECT SQL_VARIANT_PROPERTY ('','BaseType')
/*
------
varchar(1 行受影响)
*/
SELECT SQL_VARIANT_PROPERTY ('#','BaseType')/*
------
varchar(1 行受影响)
*/
-----------------
#A $
#B $
#$
CASE WHEN 中对CHAR + VARCHAR 或二者互转的话,结果为CHAR,长度为分支中最大长度指定(避免数据丢失)
这个问题,见http://blog.csdn.net/HEROWANG/archive/2009/02/22/3921339.aspx但是在2005中好像进行了优化。
在20005中,执行的时候,C转换为char(10),但是后面的''不会转换为1010个空格,所以结果是#$
用 DBCC PAGE 查看一下页面存储不就一目了然了。
我和影哥的想法一致,
前面的#和后面$,是我为了说明问题加上去的
本身的程式是只有 case ...end 那段,我抓狂要改好多地方了 可是目前还没找到官方的说法。
set @a='A'
SELECT SQL_VARIANT_PROPERTY('#'+@a,'BaseType'),DATALENGTH('#'+@a)
/*
varchar 11
*/
SELECT SQL_VARIANT_PROPERTY('#'+'A','BaseType'),DATALENGTH('#'+'A')
/*
varchar 2
*/
重点是在 case when ...我在前后加上 "#" 和 "$" 是为了表明 case when 出来的结果不一样
Create table T(id char(10))
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'select '#'+case id when 'C' then '' else id end+'$' from TDrop table T
/*sql2008
------------
#A $
#B $
#$
*/
-------sql server 2000---------
declare @str char(10)
set @str=''
select '#'+case when 1=1 then @str else '' end +'$'
union all
select '#'+case when 1<>1 then @str else '' end +'$'
/*
# $
# $
*/
go
declare @str varchar(10)
set @str=''
select '#'+case when 1=1 then @str else '' end +'$'
union all
select '#'+case when 1<>1 then @str else '' end +'$'
/*
#$
#$
*/--sql server 2005-------------
declare @str char(10)
set @str=''
select '#'+case when 1=1 then @str else '' end +'$'
union all
select '#'+case when 1<>1 then @str else '' end +'$'
/*
# $
#$
*/
go
declare @str varchar(10)
set @str=''
select '#'+case when 1=1 then @str else '' end +'$'
union all
select '#'+case when 1<>1 then @str else '' end +'$'
/*
#$
#$
*/
你去看case语法:
从 result_expressions 和可选 else_result_expression 的类型集中返回优先级最高的类型。有关详细信息,请参阅 数据类型优先级 (Transact-SQL)。
#A $
#B $
# $
SQL2000 sp4
--这样就一样了。
select '#'+case id when 'C' then '' else cast(id as varchar(10)) end+'$' from T
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'select case id when 'C' then '' else id end as Id,
case id when 'C' then SQL_VARIANT_PROPERTY('','BaseType') else SQL_VARIANT_PROPERTY(ID,'BaseType') end as IDtype,
case id when 'C' then DataLength('') else DataLength(ID) end as IDDataLength
from T
/*
Id IDtype IDDataLength
---------- ------- ------------
A char 10
B char 10
varchar 0
*/
恩,看了,但是感觉不对 case id when 'C'
then '' -- 应该是默认varchar
else id -- char(10)
end所以按online book讲的,应该出来都自动转为 varchar才对啊
但事实是,sql2000,貌似都自动转成char(10)了
而 sql2005/2008 ,则是 id 没变,还是char(10), 而''也没变,还是varchar
所以按online book讲的,应该出来都自动转为 varchar才对啊
对,按联机文档说,应该就是varchar
结果类型:从 result_expressions 和可选 else_result_expression 的类型集合中返回最高的优先规则类型所以,我觉得那引些产生"# $"的版本,全是bug吧 .
2005,确实不会转,char还是char,varchar还是varcharif object_id('t') is not null
drop table t
go
Create table T(id char(10))
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'select datalength(case when id='c' then 'A' else id end) as length from t10
10
1
#A $
#B $
#$(3 行受影响)
sql 2005
Microsoft SQL Server 2005 - 9.00.4035.00 (Intel X86) Developer Edition
--#$
Microsoft SQL Server 2005 - 9.00.1399.06 (Intel X86) Developer Edition
--#$
Microsoft SQL Server 2005 - 9.00.1399.06 (X64) Enterprise Edition (64-bit)
--# $
Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86) Developer Edition
--# $
Microsoft SQL Server 2008 (SP1) - 10.0.2531.0 (Intel X86) Standard Edition
--#$不同的版本或同版本小版本号不同,产生的结果都不相同,我汗。。
#B $
#$
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'
select '#'+case id when 'C' then '' else id end+'$' from T
Drop table T
--2008 2003server
#A $
#B $
#$
--2005 2003server
#A $
#B $
#$
Create table T(id char(10))
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'--2000
select SQL_VARIANT_PROPERTY(case id when 'C' then '' else id end,'basetype') from T--result
/*------------------------------
char
char
char(所影响的行数为 3 行)
*/--2008select SQL_VARIANT_PROPERTY(case id when 'C' then '' else id end,'basetype') from T--result
/*
---------------------------
varchar
varchar
varchar(3 行受影响)
*/
-------------------------
(所影响的行数为 1 行)
(所影响的行数为 1 行)
(所影响的行数为 1 行)
------------
#A $
#B $
# $(所影响的行数为 3 行)
---------
#A $
#B $
#$有问题的结果了没?
#A $
#B $
# $(3 row(s) affected)2000 SP3
(1 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
------------
#A $
#B $
# $(3 row(s) affected)2000表的存储原理是,对于定长数据char(10)来说,无论你存储的是一个字符'A'、'B',还是一个空字符,它都要占用10个字符的位置,所以会出现#+'中间10个字符'+$的现象发生。
至于2005的存储原理不是很了解,是不是认为空字符,则不会给它分配存储空间?
#B $
#$
Create table T(id char(10))
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'select '#'+case id when 'C' then N'' else id end+'$' from TDrop table T
后则结果与2005相同
Create table T(id char(10))
insert into T select 'A'
insert into T select 'B'
insert into T select 'C'select '#'+case id when 'C' then '' else id end+'$' from TDrop table T
#A $
#B $
# $SQL 2000 sp4
#B $
#$--SQL2005&SQL2008
------------------------
#A $
#B $
# $
------------
#A $
#B $
#$SQLServer2005 怎么能知道是SP几?
sql2005的结果是 varchar
这个按照online book的理解是应该varchar
可以撇开某些2005版本的带空格不说,
就拿id 的值本身来讲,它的后面也是带着空格的(貌似除了'' 是varchar, id本身还是char,而不是varchar)
如果同時table 是 id nchar(10)的話,就同样会出现"空格"了