我在SQL Server 2012 BI中有一个表:
CREATE TABLE CodeParts (
ID int identity(1,1) not null
,Line nvarchar(max) not null
)
加载了存储在
[Line]
列中的非常长的T-SQL查询的一部分。例:ID | Line
----------------------
1 | BEGIN TRAN MERGE someTableWithLotOfColumns dst USING (SELECT...
2 | WHEN MATCHED THEN CASE WHEN dst.someColumn != src.someColumn...
3 | WHEN NOT MATCHED...
4 | OUTPUT...
5 | ;MERGE... next table with lot of columns blah blah blah
...| ...
25 | ;MERGE... yet another table with lot of columns
60 | COMMIT
该代码有60行,由于列数及其名称的长度,每行最多可以包含12,000个字符。
我需要执行由所有这些行构建的整个代码,而且我不知道如何避免截断。
最佳答案
使用更长的字符串可能非常棘手。检查一下:
DECLARE @txt NVARCHAR(MAX)=(SELECT REPLICATE('x',12000));
SELECT LEN(@txt) AS CountCharacters
,DATALENGTH(@txt) AS UsedBytes;
尽管可能会认为这被声明为
NVARCHAR(MAX)
,但给定的'x'
不是。这使该字符串成为具有较小大小限制的普通字符串。现在尝试一下(唯一的区别是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;
为了演示这一点,我创建了一个虚拟表的工作示例,该表有60行,每行包含12.000个字符。
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
最终结果清楚地表明,结果字符串的长度为60乘以12.000(加上添加的空格),并且由于
NVARCHAR
而在内存中是此值的两倍。此串联最多可以使用〜2GB。 According to this这已经足够了:-)我认为
EXEC
能够处理NVARCHAR(MAX)
的最大大小。关于sql-server - 如何连接长的nvarchar(max)行以构建动态T-SQL,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42846910/