에서 영감 @ 폴 의 대답은 , 제가 조사를 좀 해봤 발견은 스택 공간이 제한에게 회씩 연결의 수를 않습니다, 것은 사실이지만 및 그 스택 공간이 사용 가능한 메모리의 함수이며, 따라서 다음 두 가지 사항도 참 다양합니다 :
- 추가 연결을 단일 명령문으로 작성하는 방법이 있습니다.
- 이 방법을 사용하여 초기 스택 공간 제한을 넘어 서면 실제 논리적 한계 (다양하게 보이지 않음)를 찾을 수 있습니다.
먼저 Paul의 테스트 코드를 조정하여 문자열을 연결했습니다.
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = N'
DECLARE @S VARCHAR(MAX), @A VARCHAR(MAX) = ''a'';
SET @S = @A';
SET @SQL += REPLICATE(CONVERT(NVARCHAR(MAX), N' + @A'), 3312) + N';';
-- SET @S = @A + @A + @A...
SET @SQL += N'SELECT DATALENGTH(@S) AS [Chars In @S];';
EXECUTE (@SQL);
이 테스트를 통해 그다지 우수하지 않은 랩톱 (6GB RAM 만)에서 실행할 때 얻을 수있는 가장 높은 값은 다음과 같습니다.
- SQL Server 2017 Express Edition LocalDB를 사용하는 3311 (총 3312 자 반환) (14.0.3006)
- SQL Server 2012 Developer Edition SP4 (KB4018073) (11.0.7001)를 사용한 3512 (총 3513 자 반환)
오류 점점 전에 8631을 .
다음으로, 조작이 여러 그룹의 연결을 연결하도록 괄호를 사용하여 연결을 그룹화하려고 시도했습니다. 예를 들면 다음과 같습니다.
SET @S = (@A + @A + @A + @A) + (@A + @A + @A + @A) + (@A + @A + @A + @A);
그렇게하면 이전의 3312 및 3513 변수 한계를 훨씬 뛰어 넘을 수있었습니다. 업데이트 된 코드는 다음과 같습니다.
DECLARE @SQL VARCHAR(MAX), @Chunk VARCHAR(MAX);
SET @SQL = '
DECLARE @S VARCHAR(MAX), @A VARCHAR(MAX) = ''a'';
SET @S = (@A+@A)';
SET @Chunk = ' + (@A' + REPLICATE(CONVERT(VARCHAR(MAX), '+@A'), 42) + ')';
SET @SQL += REPLICATE(CONVERT(VARCHAR(MAX), @Chunk), 762) + ';';
SET @SQL += 'SELECT DATALENGTH(@S) AS [Chars In @S];';
-- PRINT @SQL; -- for debug
-- SET @S = (@A+@A) + (@A + @A...) + ...
EXECUTE (@SQL);
최대 값 (나를 위해)은 이제 42
첫 번째 REPLICATE
에 사용되므로 그룹 당 43 개의 변수를 사용 762
하고 두 번째에 대해 REPLICATE
사용하여 43 개의 변수로 구성된 762 그룹을 사용합니다. 초기 그룹에는 두 가지 변수가 하드 코딩되어 있습니다.
이제 출력에 @S
변수에 32,768자가있는 것으로 표시 됩니다. 초기 그룹을 (@A+@A+@A)
just 대신 업데이트 (@A+@A)
하면 다음 오류가 발생합니다.
메시지 8632, 수준 17, 상태 2, 줄 XXXXX
내부 오류 : 식 서비스 제한에 도달했습니다. 쿼리에서 잠재적으로 복잡한 표현식을 찾아서 단순화하십시오.
오류 번호가 이전과 다릅니다. 지금 : 8632 . 또한 SQL Server 2012 인스턴스를 사용하든 SQL Server 2017 인스턴스를 사용하든 동일한 제한이 있습니다.
여기서 32.768의 상한값 이 ( .NET에서) 최대 용량 인 IF 의 최대 용량 (최대 값은 32,767이지만 많은 / 대부분의 프로그래밍 언어의 배열은 0 기반) 이라는 것은 우연의 일치가 아닙니다 .SMALLINT
Int16
0