我有一个表格,其中充满了一些希腊文本行,名为nvarchar(2000)。
最近,我将列的类型更改为varchar(4000),但我意识到一些希腊字符被显示为问号。
因此,我试图更改为nvarchar(4000),以修复它,因为我假设字符的unicode仍然保持不变。
我只是想知道,有没有办法来修复这个问题,而不是在更改表之前恢复我创建的备份?
发布于 2016-09-09 18:52:12
不,没有办法“修复”数据,因为数据不再存在。当您转换为VARCHAR时,每个字符的基础值被更改为?的ASCII值。这不是一个显示问题,这些字符现在在物理上是一个常规问号。不幸的是,您需要从备份中进行还原。
下面的示例代码显示,一旦将Unicode字符转换为VARCHAR (假设由排序规则表示的代码页不支持该字符),它将成为常规的'ol‘问号,并且将永远保持不变:
DECLARE @Character NCHAR(1) = NCHAR(0x3525);
SELECT @Character AS [TheCharacter],
UNICODE(@Character) AS [DecimalCodePoint],
ASCII(@Character) AS [DecimalValueOfVarchar],
UNICODE(CONVERT(VARCHAR(5), @Character)) AS [ConvertToVarchar],
UNICODE(CONVERT(NVARCHAR(5), CONVERT(VARCHAR(5), @Character)))
AS [ConvertToVarcharAndBack],
ASCII('?') AS [VarcharQuestionMark],
UNICODE(N'?') AS [UnicodeQuestionMark];
-- 㔥 13605 63 63 63 63 63下面的示例显示了一个在大多数字体中非常可疑的Unicode字符实例(至少此时如此),因此它看起来是一个方框,但是UNICODE built函数显示底层代码仍然是正确的Unicode代码点:
SELECT NCHAR(0xABBF), N'ꮿ', UNICODE(N'ꮿ');
-- ꮿ ꮿ 43967在这里可以看到实际的字符:U+ABBF切诺基小写字母YA。这是一个显示问题,许多不以不同字体表示的字符将以相同的方式显示,而不会更改字符的实际值,但它们仍然是不同的字符。
发布于 2016-09-09 19:35:19
我希望能找到一种作弊的方法,但看起来斯鲁茨基是对的。下面是一个用来证明(我认为)底层数据更改的脚本:
--build and populate table
IF OBJECT_ID('tempdb..#t') IS NOT NULL
DROP TABLE #t
CREATE TABLE #t
(txt nvarchar(1))
INSERT #t
VALUES
(N'Γ')
--show how it's stored
SELECT txt,CONVERT(varbinary,txt)
FROM #t
--Alter and show
ALTER TABLE #t
ALTER COLUMN txt varchar(2)
SELECT txt,CONVERT(varbinary,txt)
FROM #t
--And again
ALTER TABLE #t
ALTER COLUMN txt nvarchar(1)
SELECT txt,CONVERT(varbinary,txt)
FROM #thttps://dba.stackexchange.com/questions/149235
复制相似问题