SQL Server为每个sql_variant文本值存储自己的归类,因此我出于测试目的而尝试将德语到法语的字符串存储到sql_variant
中。
CREATE TABLE [dbo].[VarCollation]
(
[uid] [INT] IDENTITY (1, 1) NOT NULL,
[comment] NVARCHAR(100),
[variant_ger] [sql_variant] NULL,
[variant_rus] [sql_variant] NULL,
[variant_jap] [sql_variant] NULL,
[variant_ser] [sql_variant] NULL,
[variant_kor] [sql_variant] NULL,
[variant_fre] [sql_variant] NULL
) ON [PRIMARY]
GO
INSERT INTO VarCollation(comment, variant_ger, variant_rus, variant_jap, variant_ser, variant_kor, variant_fre)
VALUES('NVarChar',
CONVERT(NVARCHAR, N'Öl fließt') COLLATE SQL_Latin1_General_CP1_CI_AS,
CONVERT(NVARCHAR, N'Москва') COLLATE Cyrillic_General_CI_AS,
CONVERT(NVARCHAR, N' ♪リンゴ可愛いや可愛いやリンゴ。半世紀も前に流行した「リンゴの') COLLATE Japanese_CI_AS,
CONVERT(NVARCHAR, N'ŠšĐđČčĆ掞') COLLATE Serbian_Latin_100_CI_AS,
CONVERT(NVARCHAR, N'향찰/鄕札 구결/口訣 이두/吏讀') COLLATE Korean_100_CI_AS,
CONVERT(NVARCHAR, N'le caractère') COLLATE French_CS_AS);
GO
INSERT INTO VarCollation (comment, variant_ger, variant_rus, variant_jap, variant_ser, variant_kor, variant_fre)
VALUES('VarChar',
CONVERT(VARCHAR, N'Öl fließt') COLLATE SQL_Latin1_General_CP1_CI_AS,
CONVERT(VARCHAR, N'Москва') COLLATE Cyrillic_General_CI_AS,
CONVERT(VARCHAR, N' ♪リンゴ可愛いや可愛いやリンゴ。半世紀も前に流行した「リンゴの') COLLATE Japanese_CI_AS,
CONVERT(VARCHAR, N'ŠšĐđČčĆ掞') COLLATE Serbian_Latin_100_CI_AS,
CONVERT(VARCHAR, N'향찰/鄕札 구결/口訣 이두/吏讀') COLLATE Korean_100_CI_AS,
CONVERT(VARCHAR, N'le caractère') COLLATE French_CS_AS);
GO
通过分析每个sql_variant的数据,我看到存储的每个值都为NVARCHAR和VARCHAR分配了精确的排序规则。
German
collationId 0x3400d008
codepage 0x000004e4
Russian
collationId 0x0000d015
codepage 0x000004e3
Japanese
collationId 0x0000d010
codepage 0x000003a4
Serbian
collationId 0x0004d04c
codepage 0x000004e2
Korean
collationId 0x0004d040
codepage 0x000003b5
French
collationId 0x0000c00b
codepage 0x000004e4
但是SSMS会显示NVARCHAR的正确值,并显示VARCHAR的垃圾值
uid comment variant_ger variant_rus variant_jap variant_ser variant_kor variant_fre
1 NVarChar Öl fließt Москва ♪リンゴ可愛いや可愛いやリンゴ。半世紀も前に流行した「リン ŠšĐđČčĆ掞 향찰/鄕札 구결/口訣 이두/吏讀 le caractère
2 VarChar Ol flie?t Москва ?d???????????????????????????? SsDdCcCcZz ??/?? ??/?? ??/?? le caractere
从我在sql_variant数据中看到的VARCHAR日语文本存储的某些字符已被0x3f('?')替换。我尝试在没有convert
和N
的情况下插入,但结果相同。是否可以将此类文本插入sql_variant以及如何做到?
答案 0 :(得分:1)
是的,要回答您的问题,可以在sql_variant
中存储不同的排序规则,但是您的COLLATE
语句放置在错误的位置。在nvarchar
转换为varchar
之后,您正在更改值 的排序规则,因此字符已经丢失。将varchar
转换回nvarchar
或事后更改排序规则不会恢复“丢失”的数据;它已经丢失了。
即使您修复了该问题,您也会注意到,但是您没有得到想要的结果:
USE Sandbox;
GO
CREATE TABLE TestT (TheVarchar sql_variant)
INSERT INTO dbo.TestT (TheVarchar)
SELECT CONVERT(varchar, N'향찰/鄕札 구결/口訣 이두/吏讀' COLLATE Korean_100_CI_AS)
INSERT INTO dbo.TestT (TheVarchar)
SELECT CONVERT(varchar, N' ♪リンゴ可愛いや可愛いやリンゴ。半世紀も前に流行した「リンゴの' COLLATE Japanese_CI_AS);
SELECT *
FROM dbo.TestT;
GO
DROP TABLE dbo.TestT;
请注意,第二个字符串的值为' ♪リンゴ可愛いや可愛いやリン'
(已被截断)。这是因为您尚未声明varchar
的长度值。 总是声明您的长度,精度,比例等。您比我更了解您的数据,因此您会知道一个合适的值。