如何从 SQL_Latin1_General_CP1_CI_AS 中提取不相等的字符?

ber*_*d_k 4 sql-server collation

当我创建这样的表时

create table char_test(
    item varchar(10) collate SQL_Latin1_General_CP1_CI_AS
)
go
Run Code Online (Sandbox Code Playgroud)

我可以存储包含?

insert into char_test values ('?');
Run Code Online (Sandbox Code Playgroud)

当我做一个

select item from  char_test;
Run Code Online (Sandbox Code Playgroud)

我得到

item
----------
=
Run Code Online (Sandbox Code Playgroud)

但是使用

select replace(item, '?', '>=') from  char_test;
Run Code Online (Sandbox Code Playgroud)

-----------------
>=
Run Code Online (Sandbox Code Playgroud)

所以数据库知道这个字符。如何将字符串转换为显示此字符的 nvarchar?

编辑:

这里的重要事实是,这里的 SQL Server 将一些不同的字符映射到同一个字符,而不会抛出错误或警告。

我敢说这是非常糟糕的设计。

gbn*_*gbn 5

varchar 不支持?:仅 unicode

这也包括'?'varchar的文字

这里的整理无关紧要:这是排序和比较,以前从未见过!

一些更多的 SQL 来使用你的表

SELECT ASCII('?'), CHAR(61), '?'
GO
insert into char_test values ('?');
GO
select item, ASCII(item) from  char_test;
GO
select replace(item, '?', '>='), replace(item, '=', '>=') from  char_test;
GO


create table nchar_test(
    item varchar(10) collate SQL_Latin1_General_CP1_CI_AS,
    Nitem nvarchar(10) collate SQL_Latin1_General_CP1_CI_AS
)
go
insert into nchar_test values ('?', N'?');
GO
select item, ASCII(item), Nitem, UNICODE(Nitem) from nchar_test;
GO
Run Code Online (Sandbox Code Playgroud)

编辑:更多玩后

如果您有值,则使用 CP 437

select CAST(Nitem COLLATE SQL_Latin1_General_CP437_CI_AS AS varchar) from nchar_test;
GO
select CAST(N'?' COLLATE SQL_Latin1_General_CP437_CI_AS AS varchar)
GO
Run Code Online (Sandbox Code Playgroud)

注意:ASCII 是 242 但这不会给出任何一个:-)

SELECT
   ASCII(CAST(N'?' COLLATE SQL_Latin1_General_CP437_CI_AS AS varchar)),
   CHAR(242),
   CHAR(242) COLLATE SQL_Latin1_General_CP437_CI_AS
Run Code Online (Sandbox Code Playgroud)

您可以使用数据库整理来控制它,但坦率地说,使用 unicode ......