问题是您的 PhysicalTable_1 在 LName 中包含不可打印的 unicode 字符。您将 Table1 的 unicode LName NVARCHAR 列插入到 Table2 的 ascii/nonunicode LName VARCHAR 列中。Nonunicode 是 sql server 中 unicode 大小的一半,一些字节必须被“截断”,并且由于大小减小,不可打印的字符变得明显。
--characters to binary
SELECT CAST(N'P' AS VARBINARY(10)) AS UnicodeP, CAST('P' AS VARBINARY(10)) AS AsciiP --unicode is double the size of ascii
CREATE TABLE #temp(UnicodeP NVARCHAR(10), AsciiP VARCHAR(10));
INSERT INTO #temp(UnicodeP, AsciiP) VALUES (N'P', 'P'); --nothing special, normal insertion
INSERT INTO #temp(UnicodeP, AsciiP) VALUES ('P', N'P'); --omitting the N for unicode and using N for ascii, still works ok, implicit conversion
SELECT * FROM #temp;
--use binary from the very first SELECT CAST(....
INSERT INTO #temp(UnicodeP, AsciiP) VALUES (0x5000, 0x50); --still fine
SELECT * FROM #temp;
--prepend a nonprintable character (BOM) to unicode P, just insert into the UnicodeP only
INSERT INTO #temp(UnicodeP, AsciiP) VALUES (0xFEFF + 0x5000, NULL); --still fine
SELECT * FROM #temp;
--if you copy and paste the last UnicodeP, where AsciiP is NULL, you will not notice any visual difference
--update the ascii from unicode , where ascii is null
UPDATE #temp
SET AsciiP = UnicodeP --implicit conversion, ascii is half the unicode, some bytes have to go away
WHERE AsciiP IS NULL;
--since unicode was implicitly converted to ascii, some bytes are "stripped out" The nonprintable 0xFEFF needs to be "cut in half" and it becomes an unidentified char
SELECT UnicodeP, CAST(UnicodeP AS VARBINARY(10)) AS UnicodePbinary, AsciiP, CAST(AsciiP AS VARBINARY(10)) as AsciiPbinary
FROM #temp;
DROP TABLE #temp;
*编辑,隐式 unicode 到 nonunicode 和 asciiOrnothing
SELECT NCHAR(rownum) AS TheChar, CAST(NCHAR(rownum) AS CHAR(1)) AS ImplicitConversion,
CASE WHEN NCHAR(rownum) < N'Ā' collate Latin1_General_BIN2 THEN NCHAR(rownum) ELSE '' END AS AsciiOrNothing,
UNICODE(NCHAR(rownum)) AS CharInteger,
--or
CASE WHEN UNICODE(/*TheChar*/ NCHAR(rownum)) <= 255 THEN NCHAR(rownum) ELSE '' END AS AsciiOrNothing2
FROM
(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT null)) AS rownum
FROM (
--10K
SELECT TOP (100) name from master.dbo.spt_values) AS a
CROSS JOIN (SELECT TOP (100) name from master.dbo.spt_values) AS b
) AS src
ORDER BY rownum