목적
자체 참조 기능의 테스트 예제를 작성하려고 할 때 한 버전은 실패하고 다른 버전은 성공합니다.
유일한 차이점 SELECT
은 함수 본문에 추가 되어 두 실행 계획이 다릅니다.
작동하는 기능
CREATE FUNCTION dbo.test5(@i int)
RETURNS INT
AS
BEGIN
RETURN(
SELECT TOP 1
CASE
WHEN @i = 1 THEN 1
WHEN @i = 2 THEN 2
WHEN @i = 3 THEN dbo.test5(1) + dbo.test5(2)
END
)
END;
함수 호출
SELECT dbo.test5(3);
보고
(No column name)
3
작동하지 않는 기능
CREATE FUNCTION dbo.test6(@i int)
RETURNS INT
AS
BEGIN
RETURN(
SELECT TOP 1
CASE
WHEN @i = 1 THEN 1
WHEN @i = 2 THEN 2
WHEN @i = 3 THEN (SELECT dbo.test6(1) + dbo.test6(2))
END
)END;
함수 호출
SELECT dbo.test6(3);
또는
SELECT dbo.test6(2);
오류 발생
최대 저장 프로 시저, 함수, 트리거 또는 뷰 중첩 수준을 초과했습니다 (제한 32).
원인을 추측
실패한 함수의 예상 계획에 대한 추가 계산 스칼라가 있습니다.
<ColumnReference Column="Expr1002" />
<ScalarOperator ScalarString="CASE WHEN [@i]=(1) THEN (1) ELSE CASE WHEN [@i]=(2) THEN (2) ELSE CASE WHEN [@i]=(3) THEN [Expr1000] ELSE NULL END END END">
그리고 expr1000은
<ColumnReference Column="Expr1000" />
<ScalarOperator ScalarString="[dbo].[test6]((1))+[dbo].[test6]((2))">
32를 초과하는 재귀 참조를 설명 할 수 있습니다.
실제 질문
추가 SELECT
하면 함수 자체가 계속 반복되어 무한 루프가 발생하지만 왜이 SELECT
결과를 제공합니까?
추가 정보
Build version:
14.0.3045.24
compatibility_levels 100 및 140에서 테스트되었습니다.