我有下表:
Select
name,
address,
description
from dbo.users
我想在这个表中搜索任何UNICODE但不是ASCII的字符。这可能吗?
答案 0 :(得分:2)
您可以非常简单地找到非ASCII字符:
SELECT NAME, ADDRESS, DESCRIPTION
FROM DBO.USERS
WHERE NAME != CAST(NAME AS VARCHAR(4000))
OR ADDRESS != CAST(ADDRESS AS VARCHAR(4000))
OR DESCRIPTION != CAST(DESCRIPTION AS VARCHAR(4000))
答案 1 :(得分:1)
就我所知,似乎没有内置功能。蛮力方法是将每个字符传递给ascii
,然后将结果传递给char
并检查它是否返回'?',这意味着该字符超出范围。您可以使用以下代码编写UDF作为参考,但我认为这是一个非常低效的解决方案:
declare @i int = 1
declare @x nvarchar(10) = N'vsdǣf'
declare @result nvarchar(100) = N''
while (@i < len(@x))
begin
if char(ascii(substring(@x,@i,1))) = '?'
begin
set @result = @result + substring(@x,@i,1)
end
set @i = @i+1
end
select @result
答案 2 :(得分:1)
如果要确定NVARCHAR
/ NCHAR
/ NTEXT
列中是否有任何字符不能转换为VARCHAR
,则需要转换为{ {1}}使用用于该特定列的归类的VARCHAR
变体。例如,如果特定列正在使用_BIN2
,那么您将为测试指定Albanian_100_CI_AS
。使用Albanian_100_BIN2
归类的原因是,非二进制归类将仅找到其中至少一个字符在代码页中根本没有任何映射的实例,因此将其转换为_BIN2
。但是,非二进制排序规则不会捕获某些实例,这些实例的字符没有直接映射到代码页中,而是具有“最佳匹配”映射。例如,上标2字符?
在代码页1252中具有直接映射,因此绝对没有问题。另一方面,它在代码页1250中没有直接映射(由阿尔巴尼亚归类使用),但确实具有“最佳匹配”映射,可以将其转换为常规²
。非二进制排序规则的问题在于2
等于2
,因此它不会注册为不能转换为²
的行。例如:
VARCHAR
理想情况下,您将明确地转换回SELECT CONVERT(VARCHAR(MAX), N'²' COLLATE French_100_CI_AS); -- Code Page 1252
-- ²
SELECT CONVERT(VARCHAR(MAX), N'²' COLLATE Albanian_100_CI_AS); -- Code Page 1250
-- 2
SELECT CONVERT(VARCHAR(MAX), N'²' COLLATE Albanian_100_CI_AS)
WHERE N'²' <> CONVERT(NVARCHAR(MAX),
CONVERT(VARCHAR(MAX), N'²' COLLATE Albanian_100_CI_AS));
-- (no rows returned)
SELECT CONVERT(VARCHAR(MAX), N'²' COLLATE Albanian_100_BIN2)
WHERE N'²' <> CONVERT(NVARCHAR(MAX),
CONVERT(VARCHAR(MAX), N'²' COLLATE Albanian_100_BIN2));
-- 2
,以使代码清楚地知道它在做什么,尽管不这样做仍将隐式转换回NVARCHAR
,因此两种方式的行为相同
请注意,仅使用NVARCHAR
类型。请勿使用MAX
或NVARCHAR(4000)
,否则您可能会由于VARCHAR(4000)
列中的数据被截断而得到误报。
因此,根据问题中的示例代码,查询将是(假设正在使用NVARCHAR(MAX)
归类):
Latin1_General