带有OUTPUT子句的INSERT INTO TEMP表将附加字符添加到不在源中的值中

问题描述 投票:0回答:1

带有OUTPUT子句的INSERT INTO TEMP表添加了不在源中的额外字符。

例如从具有LName ='John'的现有PhysicalTable_1表记录插入后,目标PhysicalTable_1表以及#Temp表具有'?John'或'I?John' Lname,有时FName或Email以及其他字段。

PhysicalTable_1中的数据示例-FName ='Raul'插入后的目标记录看起来像='?Raul'

我正在使用此:

 CREATE TABLE #Temp 
    (
    ID INT NOT NULL,
    LName VARCHAR(75) NULL,
    FName VARCHAR(75) NULL,
    Email VARCHAR(125) NULL
    )

    CREATE TABLE PhysicalTable_2
    (
    ID INT NOT NULL,
    LName VARCHAR(75) NULL,
    FName VARCHAR(75) NULL,
    Email VARCHAR(125) NUL
    )

 CREATE TABLE PhysicalTable_1
    (
    ID INT NOT NULL,
    LName NVARCHAR(500) NULL,
    FName NVARCHAR(500) NULL,
    Email NVARCHAR(500) NULL
    )

    INSERT INTO PhysicalTable_2
    (
      LName, FName, Email
    )
    OUTPUT INSERTED.LName, INSERTED.FName, INSERTED.Email
    INTO #Temp

    SELECT LName, FName, Email
    FROM PhysicalTable_1

我还试图将#Temp表的所有字符串字段数据类型更改为NVARCHAR。目的地中的某些记录仍然有多余的字符

sql-server sql-insert temp-tables output-clause
1个回答
1
投票

问题是您的PhysicalTable_1在LName中包含不可打印的Unicode字符。您将Table1的unicode LName NVARCHAR列插入到Table2的ascii / nonunicode LName VARCHAR列中。 Nonunicode是sql服务器中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
© www.soinside.com 2019 - 2024. All rights reserved.