数据表结构如下:
CREATE TABLE [zltxSH001] (
[GroupNo] [bigint] NOT NULL ,
[data] [numeric](10, 5) NOT NULL ,

其中数据:
1 7
1 8
1 9
1 102 9
2 7
2 9
2 3
其中GroupNo为子组数,如上共有两组数,子组大小为4,我定义了一个求每个子组中位数的函数
(中位数,对于一组升序或降序排列的n个子组观测值X1,X2Xn,当n为奇数时,中位数等于该组数中间那个数,当n为偶数时,中位数等于中间两个数的平均值)函数定义
--参数列表:TableName,表名;n,子组大小;GroupNo,子组号
CREATE FUNCTION dbo.getMe(@TableName varchar(100),@n int,@GroupNo int)
RETURNS decimal(38,6)  AS  
BEGIN 
declare @Data decimal(38,6),@Count int,@DataTwo decimal(38,6),@i int
set @Count=@n/2+@n%2
exec sp_executesql 'declare cursorData cursor for select Data from  @TableName  where GroupNo=@GroupNo order by Data'
open cursorData
set @i=@Count
while(@i>0)begin
Fetch Next from cursorData
into @Data
set @i=@i-1
end
if(@Count%2=0) begin
Fetch Next from cursorData into @DataTwo
set @Data=(@Data+@DataTwo)/2
end
close cursorData
deallocate cursorData
return @Data;
END
执行:
select dbo.getMe('zltxsh001',5,1)错误提示:
服务器: 消息 557,级别 16,状态 2,过程 getMe,行 6
只有函数和扩展存储过程才能从函数内部执行。希望各位指点迷津!

解决方案 »

  1.   

    可能您的 BEGIN-END 块内包含具有副作用的语句,这在用户定义函数内是不允许的。函数副作用是对资源状态的任何永久更改,其作用域在函数以外。更改只可以对本地对象进行,如本地游标或局部变量。无法在函数内执行的操作的例子有:对数据库表的修改,对非函数本地游标的操作,发送电子邮件,试图进行目录修改和生成返回给用户的结果集。你的具体情况是因为里面包含有动态 EXECUTE 语句。
      

  2.   

    exec 不能在函数中运行,没有办法。
      

  3.   

    exec 不能在函数中运行,没有办法。
      

  4.   

    那怎么办呢?我需要表名做参数,不用exec怎么实现相关功能呢?
      

  5.   

    函数内部不能用exec,sp_executesql 甚至getdate都不可以。
      

  6.   

    函数可以是确定的或不确定的。如果任何时候用一组特定的输入值调用函数时返回的结果总是相同的,则这些函数为确定的。如果每次调用函数时即使用的是相同的一组特定输入值,返回的结果总是不同的,则这些函数为不确定的。不确定的函数会产生副作用。副作用是更改数据库的某些全局状态,比如更新数据库表或某些外部资源,如文件或网络等(例如,修改文件或发送电子邮件消息)。不允许在用户定义函数主体中内置不确定函数;这些不确定函数如下:@@CONNECTIONS @@TOTAL_ERRORS 
    @@CPU_BUSY @@TOTAL_READ 
    @@IDLE @@TOTAL_WRITE 
    @@IO_BUSY GETDATE 
    @@MAX_CONNECTIONS GETUTCDATE 
    @@PACK_RECEIVED NEWID 
    @@PACK_SENT RAND 
    @@PACKET_ERRORS TEXTPTR 
    @@TIMETICKS   
      

  7.   

    话虽如此,但函数有时确实比存储过程有用,比如:select abc+dbo.getValue() as returnValue
    用存储过程则不行.
      

  8.   

    娃哈哈,隔了两天终于想起了一些办法^O^
    也可以让某些人不说死心眼儿了,嘿嘿select IDENTITY(int,1,1) as ID,cast(QualIdenID as int) as QID,GroupNo,Data into #temp from zltxsh001 order by GroupNo,Data
    select GroupNo,Data from #temp where ID%5=3
    drop table #temp大家看,还有什么改进意见?要是identity能够直接在select里用那是最爽的了,现在我只能通过临时表来做这个工作;将来转到Oracle里要实现这个功能还得麻烦:(