请务必说明下测试环境,是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         $
#$              -- 这笔不一样。。*/

解决方案 »

  1.   

    是sql server的设定? 还是 sql2005的特性?
    知道的麻烦解释下。
      

  2.   

    #A         $
    #B         $
    #          $sql 2000
      

  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--我测试下的结果
    /* 
    sql2000 sp4 的
    ------------------------
    #A         $
    #B         $
    #          $
    */
      

  4.   

    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 T--Drop table T(所影响的行数为 1 行)
    (所影响的行数为 1 行)
    (所影响的行数为 1 行)             
    ------------ 
    #A         $
    #B         $
    #          $(所影响的行数为 3 行)
    2000
      

  5.   

    #A         $
    #B         $
    #$
    sql 2008
      

  6.   

    /*
    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         $
    #$
    */
      

  7.   

    sql2000 与 sql2005/sql2008 的结果好像是不一样的
    sql2000好像会以那个那位的属性(char(10)) 来定义,
    而sql2005不会不知道是sql server的设定问题?
    还是sql2005/sql2008 改过的特性?迷茫ing......因为要从sql2000 upgrade to sql2005,碰到这档子事,抓狂。。
      

  8.   


    #A         $
    #B         $
    #$SQL 2005
      

  9.   

    sql 2000(sp3)             
    ------------ 
    #A         $
    #B         $
    #          $(所影响的行数为 3 行)
      

  10.   


    1.char 与 nchar 结果是一样的
    2.表结构修改的可能性不大,不知道为什么当初不用varchar 。
      

  11.   

    --2005 SP3
    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 個資料列受到影響)
    */
      

  12.   

    ----------任务完成 走路
    ----------------------------------------------------------------
    -- 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 行受影响)
    */
      

  13.   


    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 行受影响)
      

  14.   


    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         $
    #          $
      

  15.   

    从联机文档看到case语法:
    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(最低)
      

  16.   

    查了下sql 2000/2005/2008的联机文档都是
    varchar优先级别比char高#A         $
    #B         $
    #$这个结果附合联机文档,而
    #A         $
    #B         $
    #          $
    不附合联机文档说法
      

  17.   


    SQL 2000 SP4测试结果:
    #A         $
    #B         $
    #          $
      

  18.   

    26樓 湖光 測的sql2005的中間有空格?
      

  19.   

    沟沟
    偶的是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         $
    #$
      

  20.   

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    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 行受影响)
      

  21.   

    #A         $
    #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) 
      

  22.   

    沟沟,
    我测试看了下执行计划,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的不清楚哦
      

  23.   

    因为ID列是char(10)的,而''是常量,所以case计算的结果也是char(10)的
      

  24.   


    ------------
    #A         $
    #B         $
    #$(3 行受影响)
    sql 2005
      

  25.   

    Create table T(id char(10)) 
    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 行受影响)
    */ 
      

  26.   

    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 T Drop table T --我测试下的结果 
    /* 
    sql2000 sp3 的 
    ------------------------ 
    #A        $ 
    #B        $ 
    #          $ 
    */ 
      

  27.   

    ------------ 
    #A         $
    #B         $
    #          $(所影响的行数为 3 行)sql2000 sp4
      

  28.   

    这个应该清楚了
    SELECT  SQL_VARIANT_PROPERTY   ('','BaseType')
    /*
    ------
    varchar(1 行受影响)
    */
      

  29.   

    不对
    SELECT  SQL_VARIANT_PROPERTY   ('#','BaseType')/*
    ------
    varchar(1 行受影响)
    */
      

  30.   

    SQL SERVER 2008
    -----------------
    #A         $
    #B         $
    #$
      

  31.   

    在2000中确实有 
    CASE WHEN 中对CHAR + VARCHAR 或二者互转的话,结果为CHAR,长度为分支中最大长度指定(避免数据丢失)
    这个问题,见http://blog.csdn.net/HEROWANG/archive/2009/02/22/3921339.aspx但是在2005中好像进行了优化。
      

  32.   

    个人看法select '#'+case id when 'C' then '' else id end+'$' from T在2000中,执行的时候,C转换为char(10),同时后面的''也会转换为10个空格,所以结果是#+10个空格+$
    在20005中,执行的时候,C转换为char(10),但是后面的''不会转换为1010个空格,所以结果是#$
      

  33.   

    可能是 SQL SERVER 2000 中,为 CHAR(10) 列赋值不足 10 字节时用空格填充,作为占位。
    用 DBCC PAGE 查看一下页面存储不就一目了然了。
      

  34.   


    我和影哥的想法一致,
    前面的#和后面$,是我为了说明问题加上去的
    本身的程式是只有 case ...end 那段,我抓狂要改好多地方了 可是目前还没找到官方的说法。
      

  35.   

    declare @a char(10)
    set @a='A'
    SELECT  SQL_VARIANT_PROPERTY('#'+@a,'BaseType'),DATALENGTH('#'+@a)
    /*
    varchar 11
    */
    SELECT  SQL_VARIANT_PROPERTY('#'+'A','BaseType'),DATALENGTH('#'+'A')
    /*
    varchar 2
    */
      

  36.   

    sql server 2000 在这里也许是考虑不周吧?
      

  37.   

    各位大大,重点不是在字串相加,
    重点是在 case when ...我在前后加上 "#" 和 "$" 是为了表明 case when 出来的结果不一样
      

  38.   


    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         $
    #$
    */
      

  39.   

    只能显示转换''成VARCHAR或者CHAR(10)了吧
      

  40.   


    -------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 +'$'
    /*
    #$
    #$
    */
      

  41.   


    你去看case语法:
    从 result_expressions 和可选 else_result_expression 的类型集中返回优先级最高的类型。有关详细信息,请参阅 数据类型优先级 (Transact-SQL)。 
      

  42.   

    只能说明sql server 2000在处理case when 和字符串相加时不够智能
      

  43.   

    ------------ 
    #A         $
    #B         $
    #          $
    SQL2000 sp4
      

  44.   

    --楼上正解。
    --这样就一样了。
    select '#'+case id when 'C' then '' else cast(id as varchar(10)) end+'$' from T
      

  45.   

    不是'' 转的,是因为#这个常量是Varchar的
      

  46.   

    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 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
    */
      

  47.   


    恩,看了,但是感觉不对 case id when 'C' 
             then ''  -- 应该是默认varchar
             else id  -- char(10)
             end所以按online book讲的,应该出来都自动转为 varchar才对啊
    但事实是,sql2000,貌似都自动转成char(10)了
    而 sql2005/2008 ,则是 id 没变,还是char(10), 而''也没变,还是varchar
      

  48.   


    所以按online book讲的,应该出来都自动转为 varchar才对啊
    对,按联机文档说,应该就是varchar
    结果类型:从 result_expressions 和可选 else_result_expression 的类型集合中返回最高的优先规则类型所以,我觉得那引些产生"#          $"的版本,全是bug吧 . 
      

  49.   

    这下搞大了,搞不好我要改一堆的sql 代码了。
      

  50.   


    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
      

  51.   

    ------------
    #A         $
    #B         $
    #$(3 行受影响)
                      sql 2005
      

  52.   

    看下楼上的朋友们贴的:
    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 
    --#$不同的版本或同版本小版本号不同,产生的结果都不相同,我汗。。
      

  53.   

    SQL2008:#A         $
    #B         $
    #$          
      

  54.   

    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 T
    Drop table T
    --2008 2003server 
    #A         $
    #B         $
    #$
    --2005 2003server 
    #A         $
    #B         $
    #$
      

  55.   

    看来还是有区别的:看测试:
    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 行受影响)
    */
      

  56.   

    鸟儿的结果有说服力,按联机文档应该是 varchar.
      

  57.   

    sql 2000
    -------------------------
    (所影响的行数为 1 行)
    (所影响的行数为 1 行)
    (所影响的行数为 1 行)             
    ------------ 
    #A         $
    #B         $
    #          $(所影响的行数为 3 行)
      

  58.   

    SQLSERVER 2008 X64
    ---------
    #A         $
    #B         $
    #$有问题的结果了没?
      

  59.   

    ------------ 
    #A         $
    #B         $
    #          $(3 row(s) affected)2000 SP3
      

  60.   

    我在SQL Server2000上测试结果
    (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的存储原理不是很了解,是不是认为空字符,则不会给它分配存储空间?
      

  61.   

    sql server 2008#A         $
    #B         $
    #$
      

  62.   

    也许是2000的规则或bug吧,改为
    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相同
      

  63.   


    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
      

  64.   

    #A        $ 
    #B        $ 
    #$--SQL2005&SQL2008          
      

  65.   

    sql2000 
    ------------------------
    #A         $
    #B         $
    #          $
      

  66.   


    ------------
    #A         $
    #B         $
    #$SQLServer2005 怎么能知道是SP几?
      

  67.   


    sql2005的结果是 varchar
    这个按照online book的理解是应该varchar
    可以撇开某些2005版本的带空格不说,
    就拿id 的值本身来讲,它的后面也是带着空格的(貌似除了'' 是varchar, id本身还是char,而不是varchar)
      

  68.   


    如果同時table 是 id nchar(10)的話,就同样会出现"空格"了
      

  69.   

    把id列改成varchar类型,就解决了。不用改太多。