详解db2中的locate等字符串函数

  • 1.建表语句:
create table AA_STU_TEST
(
  STU_ID        INTEGER generated always as identity
    primary key,
  STU_NAME      VARCHAR(20),
  STU_SPECIALTY VARCHAR(40),
  STU_SEX       VARCHAR(5),
  STU_AGE       INTEGER
);
  •  2.插入数据:
INSERT INTO INFODMS.AA_STU_TEST (STU_ID, STU_NAME, STU_SPECIALTY, STU_SEX, STU_AGE) VALUES (41, 'andibabay*12*11打', '专业1', '男', 21);
INSERT INTO INFODMS.AA_STU_TEST (STU_ID, STU_NAME, STU_SPECIALTY, STU_SEX, STU_AGE) VALUES (61, 'babay*12啊订单*', null, null, 25);
INSERT INTO INFODMS.AA_STU_TEST (STU_ID, STU_NAME, STU_SPECIALTY, STU_SEX, STU_AGE) VALUES (43, 'honey*sssssssssss', '专业1', '女', 23);
INSERT INTO INFODMS.AA_STU_TEST (STU_ID, STU_NAME, STU_SPECIALTY, STU_SEX, STU_AGE) VALUES (44, '我也会*你好', '专业3', '男', 24);
INSERT INTO INFODMS.AA_STU_TEST (STU_ID, STU_NAME, STU_SPECIALTY, STU_SEX, STU_AGE) VALUES (62, 'ssda22121*sa*cs', '', '', 23);
  • 3.详解,LEFT(ARG,LENGTH)RIGHT(ARG,LENGTH) 函数。LEFT、RIGHT函数返回ARG最左边、右边的LENGTH个字符串,ARG可以是CHAR或BINARY STRING。
SELECT left(T.STU_NAME, 3) STU_NAME, T.* FROM AA_STU_TEST T;
SELECT right(T.STU_NAME, 3) STU_NAME, T.* FROM AA_STU_TEST T;

查询结果如下:

然后我们发现,汉字占3个字节,查询资料得知,如果是GBK, 每个汉字占2个字节。如果是UTF,则占用3个字节。

  • 4. 详解,POSSTR(EXP1,EXP2)LOCATE(ARG1,ARG2,<POS>) 函数,POSSTR函数返回EXP2在EXP1中的位置。LOCATE函数在ARG2中查找ARG1第一次出现的位置,如果指定POS,则从ARG2的POS处开始查找ARG1第一次出现的位置。
SELECT POSSTR(T.STU_NAME, '*') STU_NAME, T.* FROM AA_STU_TEST T;
SELECT LOCATE('*', T.STU_NAME) STU_NAME, T.* FROM AA_STU_TEST T;

然后我们发现,两个sql效果一样,查询结果如下:(注:汉字占三个字节)

  • 5. 截取两个特殊字符“*”号之间的字符串。用到 SUBSTR(ARG1,POS,<LENGTH>) 函数,SUBSTR函数返回ARG1中POS位置开始的LENGTH个字符,如果没有指定LENGTH,则返回剩余的字符。(注意:汉字的除外,因为汉字占3个字节的原因,不考虑,为了方便自己把带汉字的字符去掉)。

 更新去掉汉字语句:

 UPDATE "INFODMS"."AA_STU_TEST" t SET t."STU_NAME" = 'andibabay*12*11' WHERE t."STU_ID" = 41
 UPDATE "INFODMS"."AA_STU_TEST" t SET t."STU_NAME" = 'babay*12dasa*' WHERE t."STU_ID" = 61
 UPDATE "INFODMS"."AA_STU_TEST" t SET t."STU_NAME" = '222d*s1' WHERE t."STU_ID" = 44

查询结果如下:

下面我们进行截取两个“*”号之间的字符,通过这些函数的用法,我们发现,LOCATE(ARG1,ARG2,<POS>) 函数比较适合。

其中,指定POS,则从ARG2的POS处开始查找ARG1第一次出现的位置。

  • 5.1 首先我们找个“*”号出现的位置,sql如下:
SELECT LOCATE('*', T.STU_NAME) Q, LOCATE('*', T.STU_NAME, LOCATE('*', T.STU_NAME) + 1) P, T.*
FROM AA_STU_TEST T;

查询结果如下:

然后二次利用 LOCATE(ARG1,ARG2,<POS>) 函数,进行截取,截取第一次“*”号之后的内容,指定 POS为字符串的长度减去第一个“*”号出现的位置, sql如下:

SELECT SUBSTR(STU_NAME, LOCATE('*', STU_NAME) + 1, LENGTH(STU_NAME) -LOCATE('*', STU_NAME)) STU_NAME,
       STU_NAME,
       LENGTH(STU_NAME) LENGTH,
       LOCATE('*', STU_NAME) position1,
       LOCATE('*', STU_NAME, LOCATE('*', STU_NAME)+1) position2
FROM AA_STU_TEST;

查询结果如下:(成功截取第一个“*”号之后的内容)

 

  • 5.2这个时候,我们通过计算,可以得到第二个“*”号和字符串LENGTH之间的关系,进行截取两个“*”号之间的内容,sql如下:
SELECT SUBSTR(STU_NAME, LOCATE('*', STU_NAME) + 1, LENGTH(STU_NAME) -LOCATE('*', STU_NAME, LOCATE('*', STU_NAME) + 1)) STU_NAME,
       STU_NAME,
       LENGTH(STU_NAME) LENGTH,
       LOCATE('*', STU_NAME) position1,
       LOCATE('*', STU_NAME, LOCATE('*', STU_NAME)+1) position2
FROM AA_STU_TEST;

 这个时候,我们执行发现报错:

 这是因为SUBSTR(ARG1,POS,<LENGTH>) 函数在截取的时候超出了截取的长度,这个时候,我们对数据过滤一下,然后进行查询:

SELECT
       STU_ID,
       SUBSTR(STU_NAME, LOCATE('*', STU_NAME) + 1, LENGTH(STU_NAME) -LOCATE('*', STU_NAME, LOCATE('*', STU_NAME) + 1)) STU_NAME,
       STU_NAME,
       LENGTH(STU_NAME) LENGTH,
       LOCATE('*', STU_NAME) position1,
       LOCATE('*', STU_NAME, LOCATE('*', STU_NAME)+1) position2
FROM AA_STU_TEST
where STU_ID in (41,61,62);

查询结果如下:

 这个时候我们发现,只有两条成功的截取到了,STU_ID 为61的没有截取成功。

这个时候,我们调整一下思路,用“*”号第二次出现的位置减去第一次出现的位置,就可以了。sql如下:

SELECT
  STU_ID,
  SUBSTR(STU_NAME, LOCATE('*', STU_NAME) + 1, LOCATE('*', STU_NAME, LOCATE('*', STU_NAME) + 1) -(LOCATE('*', STU_NAME)+1)) STU_NAME,
  STU_NAME,
  LENGTH(STU_NAME) LENGTH,
  LOCATE('*', STU_NAME) position1,
  LOCATE('*', STU_NAME, LOCATE('*', STU_NAME)+1) position2
FROM AA_STU_TEST
where STU_ID in (41,61,62);

查询结果如下:

  • 5.3针对字符串越界的情况,我们可以借用ABS(exp)函数,然后得到 最终 sql 如下:

SELECT
  STU_ID,
  SUBSTR(STU_NAME, LOCATE('*', STU_NAME) + 1, abs(LOCATE('*', STU_NAME, LOCATE('*', STU_NAME) + 1) -(LOCATE('*', STU_NAME)+1))) STU_NAME,
  STU_NAME,
  LENGTH(STU_NAME) LENGTH,
  LOCATE('*', STU_NAME) position1,
  LOCATE('*', STU_NAME, LOCATE('*', STU_NAME)+1) position2
FROM AA_STU_TEST;

 最终查询结果如下:(字段为空也不怕了)

评论 1 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:深蓝海洋 设计师:CSDN官方博客 返回首页

打赏作者

无名小卒菜

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值