如何最小化函数内的嵌套级别?
How do you minimize the nesting level within a function?
我目前遇到这个错误:
Msg 217, Level 16, State 1, Line 127
Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32)
如何最小化嵌套层数?我做了一些研究,发现有人用过 go each end 但这对我不起作用。
--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
为什么不创建人行横道 table?
而不是逐案处理所有这些问题
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,' ')
);
或者直接从查询连接到它而不是调用函数。
目前,您的嵌套问题是由于格式不正确 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');
returns A
因为这是一个标量函数,您可以使用它来查询:
select
et.EmpFederalFilingStatus
, StateFilingStatus = dbo.GetStateFilingStatus(et.EmpFederalFilingStatus,et.EmpTransferState)
from EmployeeTransfers et
像这样的标量函数会导致可怕的性能问题。只要有可能,函数应写成内联 table 值函数。
如果这不是学习练习,我建议使用人行横道 table(正如我的其他回答所解释的)。
参考:
- When is a SQL function not a function? "If it’s not inline, it’s rubbish." - Rob Farley
- Inline Scalar Functions - Itzik Ben-Gan
- Scalar functions, inlining, and performance: An entertaining title for a boring post - Adam Machanic
- TSQL User-Defined Functions: Ten Questions You Were Too Shy To Ask - Robert Sheldon
我目前遇到这个错误:
Msg 217, Level 16, State 1, Line 127
Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32)
如何最小化嵌套层数?我做了一些研究,发现有人用过 go each end 但这对我不起作用。
--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
为什么不创建人行横道 table?
而不是逐案处理所有这些问题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,' ')
);
或者直接从查询连接到它而不是调用函数。
目前,您的嵌套问题是由于格式不正确 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');
returns A
因为这是一个标量函数,您可以使用它来查询:
select
et.EmpFederalFilingStatus
, StateFilingStatus = dbo.GetStateFilingStatus(et.EmpFederalFilingStatus,et.EmpTransferState)
from EmployeeTransfers et
像这样的标量函数会导致可怕的性能问题。只要有可能,函数应写成内联 table 值函数。
如果这不是学习练习,我建议使用人行横道 table(正如我的其他回答所解释的)。
参考:
- When is a SQL function not a function? "If it’s not inline, it’s rubbish." - Rob Farley
- Inline Scalar Functions - Itzik Ben-Gan
- Scalar functions, inlining, and performance: An entertaining title for a boring post - Adam Machanic
- TSQL User-Defined Functions: Ten Questions You Were Too Shy To Ask - Robert Sheldon