我对此进行了研究,发现SQL Server中的text
列可以存储超过8000个字符。但是当我在文本列中运行下面的insert时,它只插入了8000个字符:
UPDATE a
SET [File] = b.Header + CHAR(13) + CHAR(10) + d.Detail + c.Trailer + CHAR(13) + CHAR(10) + CHAR(26)
FROM Summary a
JOIN #Header b ON b.SummaryId = a.SummaryId
JOIN #Trailer c ON c.SummaryId = a.SummaryId
JOIN #Detail d ON d.SummaryId = a.SummaryId
WHERE
a.SummaryId = @SummaryId
我试图生成一个固定宽度的平面文件,每一行应该是3900个字符长,他们在各自的临时表。但是当我在永久表中执行插入操作时,Trailer数据被截断。
我正在添加char(10) + char(13)来添加回车和换行以及char(26)作为文件结束,似乎它们正在向固定宽度布局添加字符。
根据http://msdn.microsoft.com/en-us/library/ms187993.aspx, TEXT
字段已弃用。使用VARCHAR(MAX)
字段代替。他们应该支持2GB的文本
代码的问题不在于存储值的字段的数据类型,而在于存储在其中的值的类型。
b.Header
的类型不是text
,而是varchar
,作为整个表达式的类型。当串接字符串时,结果将被截断以适合varchar
值。
如果将第一个字符串强制转换为text
,则整个表达式将获得该类型,并且可以超过8000个字符:
SET [File] = cast(b.Header as text) + CHAR(13) + CHAR(10) + d.Detail + c.Trailer + CHAR(13) + CHAR(10) + CHAR(26)
自然你应该转换到使用新的类型varchar(max)
而不是text
,但这不是你的问题的原因。
您的源字段不是VARCHAR(MAX)
,因此在将它们连接在一起时有8000个字符限制,您可以通过将concat列表中的第一个源字段转换为VARCHAR(MAX)
来修复此问题:
UPDATE a
SET [File] = CAST(b.Header AS VARCHAR(MAX)) + CHAR(13) + CHAR(10) + d.Detail + c.Trailer + CHAR(13) + CHAR(10) + CHAR(26)
FROM Summary a
JOIN #Header b ON b.SummaryId = a.SummaryId
JOIN #Trailer c ON c.SummaryId = a.SummaryId
JOIN #Detail d ON d.SummaryId = a.SummaryId
WHERE a.SummaryId = @SummaryId
如果您将1000个VARCHAR(25)
字段连接在一起,则结果字符串的长度将是8000,因为这是VARCHAR()
类型在提供数字长度时的限制。VARCHAR(MAX)
没有这个限制,但是concat列表继承第一个提供的字符串的类型。这是一个有趣的行为,但这就是它的工作方式。
TEXT
已弃用-不要使用它!使用VARCHAR(MAX)
代替!
我认为你需要显式地将你在UPDATE
语句中使用的所有列转换为VARCHAR(MAX)
,以使其工作:
UPDATE a
SET [File] = CAST(b.Header AS VARCHAR(MAX)) + CHAR(13) + CHAR(10) +
CAST(d.Detail AS VARCHAR(MAX)) + CAST(c.Trailer AS VARCHAR(MAX))) + CHAR(13) + CHAR(10) + CHAR(26)
FROM Summary a
JOIN #Header b ON b.SummaryId = a.SummaryId
JOIN #Trailer c ON c.SummaryId = a.SummaryId
JOIN #Detail d ON d.SummaryId = a.SummaryId
WHERE
a.SummaryId = @SummaryId