我在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/

10-14 15:42
查看更多