create table [tb]([姓名] int,[学年] int,[科目] varchar(4),[成绩] int)
insert [tb]
select 1,1,'语文',80 union all
select 1,1,'数学',60 union all
select 2,1,'语文',50 union all
select 2,1,'化学',40 union all
select 2,2,'语文',75
--select * from [tb]
--创建函数
if object_id('fn_str') is not null
    drop function fn_str
go
create function fn_str(@name int,@year int)
returns varchar(100)
as
begin
    declare @s varchar(100)    select @s=isnull(@s+';','')+科目+','+rtrim(成绩)  《--这里如果我给@S='',得到的结果就错了,请问下是如何理解的~@s初始值是不是为NULL
    from tb 
    where 姓名=@name and 学年=@year

    return @s
end
go
--测试:
select 姓名,学年,全部成绩=dbo.fn_str(姓名,学年),总成绩=sum(成绩)
from tb
group by 姓名,学年
谢谢了

解决方案 »

  1.   


    declare @s varchar(100)
    set @s = ''  -- 初始化
      

  2.   

    declare @s varchar(100)
    set @s = ''  -- 初始化
    --or
    isnull(@s,'')
      

  3.   

    -- 参考这个, 这样就可以不做 is null 处理
    if object_id('fn_str') is not null 
        drop function fn_str 
    go 
    create function fn_str(@name int,@year int) 
    returns varchar(100) 
    as 
    begin 
      declare @s varchar(100) 
    set @s = '' -- 初始化
        select @s=@s+';'+科目+','+rtrim(成绩)  --这里如果我给@S='',得到的结果就错了,请问下是如何理解的~@s初始值是不是为NULL 
        from tb 
        where 姓名=@name and 学年=@year 
        return stuff(@s, 1, 1, '') -- 把第一个多余的字符去掉 
    end 
    go 
      

  4.   

    @s初始时是为null.
    第一行时,@s为null,@s+';'也为null,所以isnull(@s+';','')就取后面那个值''.
    当循环到结果集的第二行时,@s就不为null,因此以后isnull(@s+';','')就一直取@s+';'.