Как хранить различные параметры сортировки в SQL Server типа sql_variant? - PullRequest
0 голосов
/ 05 апреля 2019

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 и как это сделать?

1 Ответ

1 голос
/ 05 апреля 2019

Чтобы ответить на ваш вопрос, да, вы можете хранить различные параметры сортировки в 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. Всегда объявляйте свою длину, точность, масштаб и т. Д. Вы знаете свои данные лучше, чем я, поэтому вы будете знать соответствующее значение для них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...