set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER function [dbo].[getMID](@MID int)
returns varchar(500)
as
begin
declare @MIDS varchar(200)
set @MIDS=''
;with cte as
(
select MID,MPID from Member_Tbl where MID=@MID
union all
select m.MID,m.MPID from cte inner join Member_Tbl m on cte.MID=m.MPID
)
select @MIDS=@MIDS+','+convert(varchar(100),MID) from cte
set @MIDS=stuff(@MIDS,1,1,'')
return @MIDS
end--执行--
select * from Member_Tbl where charindex(','+convert(varchar(200),MID)+',',','+dbo.getMID(1)+',')>0sql函数的执行效率怎么样呢?

解决方案 »

  1.   


    那我上面那个语句该怎么改呢?
    Member_Tbl这个表的数据后期还蛮多的!
      

  2.   

    数据量过多的时候不建议使用自定义函数。函数的效率也觉得于你在函数里面做了什么操作原来是.net区的Star兄
      

  3.   

    主要是因为要用在分页存储过程当条件选择
    对于sql 自己只能做到这步了,该怎么改呢?
      

  4.   

    对sql不精通,跑来sql板块当新人
      

  5.   


    declare @t table (MID int,MPID int)
    insert into @t
    select 1,0 union all
    select 2,1 union all
    select 3,2 union all
    select 4,0 union all
    select 5,0DECLARE @i INT;SET @i=1 --参数自己改
    ;WITH maco AS
    (select * from @t WHERE mid=@i UNION ALL
    SELECT a.* FROM @t a,maco WHERE a.MPID=maco.MID)SELECT * FROM maco
    /*
    MID         MPID
    ----------- -----------
    1           0
    2           1
    3           2
    */直接得到下级列表
      

  6.   

    谢谢叶子
    可是要用在存储过程分页里,取得MID当作参数处理的,
    ;with xx as没地方加额
    不知道我说的明白不?
      

  7.   

    如果要用那个分页存储过程的话,就需要用函数封装成条件。但是用;with xx as的话,可以不用固定的分页存储过程。例如create proc procname
    (
    @pageindex INT, --1
    @pagesize INT,--2
    @MID  int
    )
    AS
    begin
    declare @t table (MID int,MPID int)
    insert into @t
    select 1,0 union all
    select 2,1 union all
    select 3,2 union all
    select 4,0 union all
    select 5,0 DECLARE @i INT;SET @i=1 --参数自己改
    ;WITH maco AS
    (select * from @t WHERE mid=@i UNION ALL
    SELECT a.* FROM @t a,maco WHERE a.MPID=maco.MID)    SELECT * FROM 
        (
    SELECT ROW_NUMBER() OVER (ORDER BY mid) AS rowid, * FROM maco
    ) bb
    WHERE rowid 
    BETWEEN (@pageindex-1)*@pagesize+1 and @pageindex*@pagesize
    ENDEXEC procname 1,2,1
    /*
    rowid                MID         MPID
    -------------------- ----------- -----------
    1                    1           0
    2                    2           1
    */
    EXEC procname 2,2,1
    /*
    rowid                MID         MPID
    -------------------- ----------- -----------
    3                    3           2
    */
      

  8.   

    可以 表名
    string tablename = "Orders_Tbl o inner join Products_Tbl p on o.ID=p.ID"这样
      

  9.   

    建议你还是用我写的存储过程进行扩展一下tablename这个位置不能放入with表达式
      

  10.   

    总的来说,SQL的自定义函数效率是没法保证的,躲不开的时候应该设法用CLR函数来代替或者只有在确定函数处理的数据量能控制在很小的范围(最多就只有几千行)的情况下才使用。
      

  11.   

    数据量大了,使用递归效率就差了,这个貌似不是sql的问题,是个通病吧
      

  12.   

    如果知道数据量大,需求是需要这样查询的,可以在表结构上避免使用递归算法。比如,树形结构表增加一个冗余字符字段path,并建立索引,那一个节点(比如path=1.1.1)的所有下级都符合 path like '1.1.1.%',这个like虽然效率不太高,但是还是使用索引seek的,算是一个效率和一致性折中的方法。