如何最小化函数内的嵌套级别?

时间:2017-03-18 16:21:13

标签: sql-server-2008 user-defined-functions

我目前收到此错误:

  

Msg 217,Level 16,State 1,Line 127
  超出最大存储过程,函数,触发器或视图嵌套级别(限制32)

如何最小化嵌套级别?我做了一些研究,看到有人用过每一端,但这对我没用。

--Function: StateFilingStatus
create function dbo.GetStateFilingStatus(@EmpFederalFilingStatus char(1), @EmpTransferState char(2))
returns char(1)
as
begin
    declare @StateFilingStatus char;

    if (@EmpTransferState = 'MS') 
    begin
        if (@EmpFederalFilingStatus = 'S')
            set @StateFilingStatus = 'A';
        else
            set @StateFilingStatus = 'M';
    end
    else if (@EmpTransferState = 'NJ') 
    begin
         if (@EmpFederalFilingStatus = 'S')
             set @StateFilingStatus = 'B';
         else
             set @StateFilingStatus = 'A';
    end
    else if (@EmpTransferState = 'AZ') 
    begin
        if (@EmpFederalFilingStatus = 'S')
            set @StateFilingStatus = 'A';
        else
            set @StateFilingStatus = 'B';
    end
    else if (@EmpTransferState = 'CT') 
    begin
         if (@EmpFederalFilingStatus = 'S')
            set @StateFilingStatus = 'F';
         else
            set @StateFilingStatus = 'M';
    end
    else if (@EmpTransferState = 'DC') 
    begin
        if (@EmpFederalFilingStatus = 'S')
            set @StateFilingStatus = 'S';
        else
            set @StateFilingStatus = 'Y';
    end
    else
    begin   
        if (@EmpFederalFilingStatus = 'S')
            set @StateFilingStatus = 'S';
        else
            set @StateFilingStatus = 'M';
    end

    return (select dbo.GetStateFilingStatus(EmpFederalFilingStatus, EmpTransferState) as StateFilingStatus
            from EmployeeTransfers)
end
go

select dbo.GetStateFilingStatus('M','NJ')  as StateFilingStatus

2 个答案:

答案 0 :(得分:1)

目前,您的嵌套问题来自错误形成的return

而不是:

return(
    select dbo.GetStateFilingStatus(EmpFederalFilingStatus, EmpTransferState) as StateFilingStatus
    from EmployeeTransfers
)

你会使用:

  return @StateFilingStatus;

rextester演示:http://rextester.com/DJM36125

--Function: StateFilingStatus
create function dbo.GetStateFilingStatus(
    @EmpFederalFilingStatus char(1)
  , @EmpTransferState char(2)
  )
returns char(1) as
begin;
  declare @StateFilingStatus char(1);
  if (@EmpTransferState = 'MS') 
  begin;
    if (@EmpFederalFilingStatus = 'S')
      set @StateFilingStatus = 'A';
    else
      set @StateFilingStatus = 'M';
  end;
  else
  if (@EmpTransferState = 'NJ') 
  begin;
    if (@EmpFederalFilingStatus = 'S')
      set @StateFilingStatus = 'B';
    else
      set @StateFilingStatus = 'A';
  end;
  else
  if (@EmpTransferState = 'AZ') 
  begin;
    if (@EmpFederalFilingStatus = 'S')
      set @StateFilingStatus = 'A';
    else
      set @StateFilingStatus = 'B';
  end;
  else
  if (@EmpTransferState = 'CT') 
  begin;
    if (@EmpFederalFilingStatus = 'S')
      set @StateFilingStatus = 'F';
    else
      set @StateFilingStatus = 'M';
  end;
  else
  if (@EmpTransferState = 'DC') 
  begin;
    if (@EmpFederalFilingStatus = 'S')
      set @StateFilingStatus = 'S';
    else
      set @StateFilingStatus = 'Y';
  end;
  else
  begin   
    if (@EmpFederalFilingStatus = 'S')
      set @StateFilingStatus = 'S';
    else
      set @StateFilingStatus = 'M';
  end;
  return @StateFilingStatus;
end;
go
select StateFilingStatus = dbo.GetStateFilingStatus('','NJ');

返回A

由于这是一个标量函数,你可以使用它来查询:

select 
    et.EmpFederalFilingStatus
  , StateFilingStatus = dbo.GetStateFilingStatus(et.EmpFederalFilingStatus,et.EmpTransferState)
from EmployeeTransfers et

这样的标量函数会导致可怕的性能问题。只要有可能,函数应该写成内联表值函数。

如果这是学习练习以外的任何内容,我建议使用人行横道表(正如我的其他答案所解释的那样)。

参考:

答案 1 :(得分:0)

不是根据具体情况处理所有这些,为什么不创建一个人行横道表呢?

create table Filing_State_xwalk (
    TransferState char(2) not null
  , FederalStatus char(1) not null
  , StateStatus   char(1) not null
  , constraint pk_Filing_State_xwalk 
      primary key (TransferState, FederalStatus)
);
insert into Filing_State_xwalk values
 ('MS','S','A')
,('MS',' ','M')
,('NJ','S','B')
,('NJ',' ','A')
,('AZ','S','A')
,('AZ',' ','M')
,('CT','S','F')
,('CT',' ','M')
,('DC','S','S')
,('DC',' ','Y');

并在如此程序中使用它:

set @StateFilingStatus = (
  select StateStatus
  from Filing_State_xwalk
  where TransferState = @EmpTransferState
    and FederalStatus = coalesce(@EmpFederalFilingStatus,' ')
);

或直接从查询加入,而不是调用函数。