ฉันเข้าใจว่ามีชุดสูงสุด 4000 สำหรับ NVARCHAR(MAX)
ความเข้าใจของคุณผิด nvarchar(max)สามารถจัดเก็บข้อมูลได้มากถึง (และบางครั้ง) 2GB (1 พันล้านอักขระไบต์คู่)
จากnchar และ nvarcharในหนังสือออนไลน์ไวยากรณ์คือ
nvarchar [ ( n | max ) ]
|หมายถึงตัวละครเหล่านี้เป็นทางเลือก เช่นคุณระบุอย่างใดอย่างหนึ่ง หรือตัวอักษรnmax
หากคุณเลือกระบุเฉพาะค่าnนี้จะต้องอยู่ระหว่าง 1 ถึง 4,000 แต่การใช้maxกำหนดเป็นประเภทข้อมูลออบเจ็กต์ขนาดใหญ่ (แทนที่ntextซึ่งเลิกใช้งานแล้ว)
ในความเป็นจริงใน SQL Server 2008 ดูเหมือนว่าสำหรับตัวแปรขีด จำกัด 2GB สามารถเกินได้อย่างไม่มีกำหนดโดยมีพื้นที่ว่างเพียงพอในtempdb( แสดงที่นี่ )
เกี่ยวกับส่วนอื่น ๆ ของคำถามของคุณ
การตัดทอนเมื่อเชื่อมต่อกันขึ้นอยู่กับประเภทข้อมูล
varchar(n) + varchar(n) จะตัดที่ 8,000 อักขระ
nvarchar(n) + nvarchar(n) จะตัดที่ 4,000 อักขระ
varchar(n) + nvarchar(n)จะตัดที่ 4,000 อักขระ nvarcharมีลำดับความสำคัญสูงกว่าดังนั้นผลลัพธ์ก็คือnvarchar(4,000)
[n]varchar(max)+ [n]varchar(max)จะไม่ตัดทอน (สำหรับ <2GB)
varchar(max)+ varchar(n)จะไม่ตัดทอน (สำหรับ <2GB) และผลลัพธ์จะถูกพิมพ์เป็นvarchar(max).
varchar(max)+ nvarchar(n)จะไม่ตัดทอน (สำหรับ <2GB) และผลลัพธ์จะถูกพิมพ์เป็นnvarchar(max).
nvarchar(max)+ varchar(n)ก่อนอื่นจะแปลงvarchar(n)อินพุตเป็นnvarchar(n)แล้วทำการต่อข้อมูล ถ้าความยาวของ varchar(n)สตริงเป็นจำนวนมากกว่า 4,000 ตัวอักษรหล่อจะได้รับการnvarchar(4000)และการตัดจะเกิดขึ้น
ประเภทข้อมูลของตัวอักษรสตริง
ถ้าคุณใช้Nคำนำหน้าและสตริงคือ <= 4,000 ตัวอักษรก็จะมีการพิมพ์เป็นnvarchar(n)ที่nมีความยาวของสตริง ดังนั้นN'Foo'จะถือว่าเป็นnvarchar(3)ตัวอย่าง หากสตริงมีความยาวเกิน 4,000 อักขระจะถือว่าเป็นnvarchar(max)
หากคุณไม่ได้ใช้Nคำนำหน้าและสตริงคือ <= 8,000 ตัวอักษรก็จะมีการพิมพ์เป็นvarchar(n)ที่nมีความยาวของสตริง ถ้านานกว่านั้นvarchar(max)
สำหรับทั้งสองข้อข้างต้นหากความยาวของสตริงเป็นศูนย์nให้ตั้งค่าเป็น 1
องค์ประกอบไวยากรณ์ที่ใหม่กว่า
1.CONCATฟังก์ชั่นไม่ได้ช่วยที่นี่
DECLARE @A5000 VARCHAR(5000) = REPLICATE('A',5000);
SELECT DATALENGTH(@A5000 + @A5000),
DATALENGTH(CONCAT(@A5000,@A5000));
ข้างต้นจะคืนค่า 8000 สำหรับทั้งสองวิธีการต่อกัน
2.ระวังด้วย+=
DECLARE @A VARCHAR(MAX) = '';
SET @A+= REPLICATE('A',5000) + REPLICATE('A',5000)
DECLARE @B VARCHAR(MAX) = '';
SET @B = @B + REPLICATE('A',5000) + REPLICATE('A',5000)
SELECT DATALENGTH(@A),
DATALENGTH(@B);`
ผลตอบแทน
-------------------- --------------------
8000 10000
โปรดทราบว่า@Aพบการตัดทอน
วิธีแก้ไขปัญหาที่คุณพบ
คุณได้รับการตัดทอนเนื่องจากคุณกำลังเชื่อมต่อmaxประเภทข้อมูลที่ไม่ใช่สองประเภทเข้าด้วยกันหรือเนื่องจากคุณกำลังเชื่อมvarchar(4001 - 8000)สตริงเข้ากับสตริงที่nvarcharพิมพ์ (คู่nvarchar(max))
เพื่อหลีกเลี่ยงปัญหาที่สองเพียงให้แน่ใจว่าทุกตัวอักษรของสตริง (หรืออย่างน้อยผู้ที่มีความยาวใน 4001-8000 ช่วง) Nจะนำเข้าด้วย
เพื่อหลีกเลี่ยงปัญหาแรกให้เปลี่ยนงานจาก
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = 'Foo' + 'Bar' + ...;
ถึง
DECLARE @SQL NVARCHAR(MAX) = '';
SET @SQL = @SQL + N'Foo' + N'Bar'
เพื่อให้ an NVARCHAR(MAX)มีส่วนร่วมในการเชื่อมต่อตั้งแต่เริ่มต้น (เนื่องจากผลของการเรียงต่อกันแต่ละครั้งจะเป็นการNVARCHAR(MAX)เผยแพร่ด้วย)
หลีกเลี่ยงการตัดทอนเมื่อรับชม
ตรวจสอบให้แน่ใจว่าคุณได้เลือกโหมด "ผลลัพธ์เป็นตาราง" แล้วจึงจะสามารถใช้ได้
select @SQL as [processing-instruction(x)] FOR XML PATH
ตัวเลือก SSMS ช่วยให้คุณกำหนดความยาวได้ไม่ จำกัด สำหรับXMLผลลัพธ์ processing-instructionบิตหลีกเลี่ยงปัญหาเกี่ยวกับตัวอักษรเช่นการแสดงขึ้นเป็น<<