如何使用 DB2 函数查找字符串中每个字符的 ASCII?

Posted

技术标签:

【中文标题】如何使用 DB2 函数查找字符串中每个字符的 ASCII?【英文标题】:How to find ASCII of every character in string using DB2 Function? 【发布时间】:2019-12-24 20:00:14 【问题描述】:

我在 DB2 中编写了一个函数——计算特定列中记录的 ASCII。我想要一些帮助,因为我想检查字符串中每个字符的 ASCII,如果该记录的 ASCII 大于 127,则返回 yes。

BEGIN
ATOMIC DECLARE POS,
INT;

IF INSTR IS NULL THEN RETURN NULL;

END IF;

SET
(
    POS,
    LEN
)=(
    1,
    LENGTH(INSTR)
);


WHILE POS <= LEN DO IF ASCII( SUBSTR( INSTR, POS, 1 ))> 128 THEN RETURN 'Y';

END IF;

SET
POS = POS + 1;

END WHILE;


RETURN 'N';

【问题讨论】:

我认为使用正则表达式要容易得多。见***.com/questions/4763757/…。 是的,我也写过正则表达式。但首先我想从数据库中的特定表中取出所有特殊字符。该表有数百万条记录。为此,我正在考虑编写一个函数,该函数将为我提供具有 ascii 大于 127 的特殊字符的记录。我想计算该列中每个字符的 ascii。 【参考方案1】:

如果目标只是获取这样的行,为什么要计算该列中每个字符的 ascii?

SELECT STR
FROM 
(
VALUES 
  'Hello, world'
, 'Привет, мир'
) T (STR)
WHERE xmlcast(xmlquery('fn:matches($s, "[^\x00-\x7F]")' passing t.str as "s") as int) = 1;

fn:matches 函数使用正则表达式。[^\x00-\x7F] 正则表达式的意思是“一个十六进制值不在0x00 - 0x7F 区间内的字符”。如果传递的t.str 的值包含这样的字符,则函数返回 1,否则返回 0。

【讨论】:

你能解释一下这个查询吗? 十六进制值不在 0x00 - 0x7F 区间内的字符是什么意思?除了这些意味着额外的字符? S-ASCII 是一个字符集(和一种编码),具有一些显着的特性: 值介于 0–127 (x00–x7F) ASCII 代码点 32(十进制)表示 SPACE ASCII 代码-点65代表大写字母A【参考方案2】:

检查 DB2 中的 UTF-8 值是否仅包含“纯 ASCII”的一种简单方法是将其 BYTE 长度与 STRINGUNITS32 长度进行比较。例如

SELECT
    S
,   LENGTHB(S) AS BYTES
,   LENGTH4(S) AS CHARACTERS 
,   LENGTHB(S) = LENGTH4(S) PLAIN_ASCII
FROM 
    TABLE(VALUES ('123!"$'),('¹²³€½¾')) T(S)

返回

S     |BYTES|CHARACTERS|PLAIN_ASCII
------|-----|----------|-----------
123!"$|    6|         6|true       
¹²³€½¾|   13|         6|false      

以上假设您的数据库是 Unicode,列是 VARCHAR。如果它们是 VARGRAPHIC(即 UTF-16),那么您需要在比较中将它们转换为 VARCHAR

【讨论】:

以上是关于如何使用 DB2 函数查找字符串中每个字符的 ASCII?的主要内容,如果未能解决你的问题,请参考以下文章

ISDATE 相当于 DB2

查找DB2中varchar列中最后一次出现的空格('')

通用固定长度编码格式的字符串查找算法的实现

db2报错信息为‘字符串函数中的长度或位置超出范围’是啥意思

如何调用采用日期参数的 DB2 AS400 表值函数

db2 对字符串进行分隔(分隔符为逗号),并计算分隔得到的数组的长度,不写自定义函数,如何做到?