It can be very tricky to work with longer string. Check this:
DECLARE @txt NVARCHAR(MAX)=(SELECT REPLICATE('x',12000));
SELECT LEN(@txt) AS CountCharacters
,DATALENGTH(@txt) AS UsedBytes;
Although one might think this is declared as NVARCHAR(MAX) the given 'x' isn't. This let's the string be a normal string with a smaller size limit. Now try this (only difference is the CAST('x' AS NVARCHAR(MAX))):
DECLARE @txt2 NVARCHAR(MAX)=(SELECT REPLICATE(CAST('x' AS NVARCHAR(MAX)),12000));
SELECT LEN(@txt2) AS CountCharacters
,DATALENGTH(@txt2) AS UsedBytes;
To demonstrate this I create a working example with a dummy table with 60 row each row consisting of 12.000 characters.
DECLARE @tbl TABLE(ID INT IDENTITY,CodeLine NVARCHAR(MAX));
WITH TallySixty AS (SELECT TOP 60 ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS Dummy FROM master..spt_values)
INSERT INTO @tbl
SELECT REPLICATE(CAST(RIGHT(Dummy,1) AS NVARCHAR(MAX)),12000)
FROM TallySixty;
SELECT CodeLine,LEN(CodeLine) AS CountCharacters
,DATALENGTH(CodeLine) AS UsedBytes FROM @tbl
DECLARE @concatString NVARCHAR(MAX)=
(
SELECT(SELECT CodeLine + ' ' FROM @tbl FOR XML PATH(''),TYPE).value('(text())[1]','nvarchar(max)')
);
SELECT @concatString
,LEN(@concatString) AS CountCharacters
,DATALENGTH(@concatString) AS UsedBytes
The final result shows clearly, that the resulting string has the length of 60 times 12.000 (plus the added blanks) and is twice this sice in memory due to NVARCHAR. Up to ~2GB this concatenation should work. According to this this is pretty much enough :-)
I think, that EXEC is able to deal with NVARCHAR(MAX) up to the full size.