zoukankan      html  css  js  c++  java
  • pl/sql学习(6): 引号/程序调试/列中的字符串合并/正则表达式

    有关自治事务的问题: https://www.cnblogs.com/princessd8251/p/4132649.html

    我在plsql development学习中遇到的常见问题:

    (一) 引号

    Oracle 中的单引号与双引号有着完全不同的意义. 单引号用于界定字符串, 双引号用于表示对象名称,,,三个单引号啥情况?

    insert into student (123, '''张三');
    select * from  student;
    --得到
    123 '张三

    解释: 连续三个单引号,第一个是字符串界定符,第二个是转义符, 第三个是被转义的字符.

    update student set name ='''张三''' where sno=123;
    select * from student ;  --得到
     123  '张三'

    解释: 三个连续的单引号, 前两个用于转义并获得原义单引号, 第三个是字符串界定符的结尾符.

    insert into student (123, ''张三');-- 报错, 引号没有正常结束!

    总结: Oracle 遇到字符串的第一个单引号时, 解析为字符串界定符的开始符, 遇到第二个,解释为界定字符串的结束符,但是有第三个单引号存在时, 第二第三个引号解释为原义单引号,

    依次类推, Oracle 会寻找下一个单引号作为字符串界定结束符.

    ''张三' 为啥报错? : 第一个是字符串界定开山符, 第二个解释为字符串界定结束符, 但是后面又是 张三, 整个被认为是非法字符串.

    (二)实现一个procedure 的调试

    假设已经有了一张表: emp

    step1: 创建一个procedure 名字为proc_xy

    create or replace procedure proc_xy(v_deptno in varchar2)
    is begin
    declare
    type emp_cursor is ref cursor;
    emp_cur emp_cursor;
    v_empno varchar2(10);
    v_ename varchar2(10);
    begin
    open emp_cur for select ename, empno from emp where deptno=v_deptno;--打开与select一起
    loop 
      fetch emp_cur into v_empno,v_ename;
      
      dbms_output.put_line(v_empno||'_'||v_ename);
      exit when emp_cur%notfound;
      end loop;
    close emp_cur;
    end;
    end;

     step2: 在左侧的菜单栏中找到 proc_xy

    右键proc_xy 先选择添加调试信息!! 这很重要, 否则不能单步调试了.

    step3: 右键 选择->测试, 进入测试界面,

    然后在下方输入这个procedure 的输入参数, 

    第一个为开始调试, 第三个是单步调试,下方可以输入想要查看的变量名称.我这里输入的是v_ename,

    每次点击"单步调试" 就可以看到变量的变化, 当出现问题的时候, 会终止运行并自动识别出来!

     (三) 强大的wmsys.wm_concat, 实现字符串合并

    已知一张表bbb

    现在想要把相同id1 的name1进行合并,如何操作?

    select id1, wmsys.wm_concat(name1) name_all from bbb group by id1;

    得到: 

    结果是clob 形式, 点击打卡可以看到具体内容

    如何把clob 转为string 类型?

     select id1, dbms_lob.substr(wmsys.wm_concat(name1),1000,1) name_all from bbb group by id1; 

    20180901 补充: 其中也可以用to_char()  就行了, to_char(wm_concat(name1)) 

    得到:

    进一步: 如果需要将字符串进行转变, 每个字符串加*  建立函数

    create or replace function func1(str1 in varchar2) return varchar2
    is 
    str2 varchar2(100);
    begin
    str2:=concat(str1,'*');
    return str2;
    end;

    直接可以调用函数func1

    select id1, dbms_lob.substr(wmsys.wm_concat(func1(name1)),1000,1) name_all from bbb group by id1;

    得到:

     进一步: 上述的wm_concat 是逗号分隔,  如何指定分隔符? listagg

    -- 用listagg,可以指定的分割符号 
    select id1, listagg(name1,'*') within group(order by name1) name_all from bbb group by id1; -- 根据name1的顺序排布

    得到

    注意: 如果列的数据类型不是char , 那么需要转一下?

    -- 如果列不是char 类型, 那么to_char
    LISTAGG( to_char(列名), ',') WITHIN GROUP(ORDER BY 列名)

     但是我实际操作没有问题.. 已知表ccc, sal 是number

       

    select id1, wmsys.wm_concat(sal) sal_all from ccc group by id1;
    select id1, dbms_lob.substr(wm_concat(sal),1000,1) sal_all from ccc group by id1;

    没有写 to_char  得到结果也是对的

      

    用listagg 也没有报错

    select id1, listagg(sal,'*') within group(order by sal) sal_all from ccc group by id1;

    结果为: 

    当然 select id1, listagg(to_char(sal),'*') within group(order by sal) sal_all from ccc group by id1; 也没有错!

     (四) 正则表达式

    Oracle 10g 之后的版本都是支持正则表达式.

    这里的正则表达式与Python 一样的, 都是通用标准用法的, 具体每个保留字 的含义可以见我的另一片博文.

    具体函数介绍

    (1) regexp_like()

    regexp_like(expression, regexp) 第一个参数为源字符串, 第二个是用于匹配的正则表达式. 函数返回值为bool 值, True / False

    select * from emp where regexp_like(ename, '^J.*$');
    -- J 开头,后面任意个数的结尾
    -- 也可以用like , %通配符, 实现上述功能 
    select * from emp where ename  like 'J%' ;

    注意: 如何忽略大小写?

    select * from emp where regexp_like(ename, 'or','i');-- i 表示ignore
    -- 结果得到 Jordan, Oracle 这两个人

    (2) regexp_instr()

    regexp_instr(expression, regexp, startindex, times), 

    startindex 为开始匹配的位置, times 为第几次匹配结果最为最终的结果, 这两个参数默认都是1.

    select regexp_instr('12.243','.') position from dual;-- 结果是3

    (3) regexp_substr()

    regexp_substr(expression, regexp)  返回匹配的字符串

    (4) regexp_replace(expression, regexp,replacement)

    ----END---- HAVE A GOOD ONE! 以上为本人课余自学工具书/blog的笔记整理, 常有更新, 非100%原创!且读且学习。
  • 相关阅读:
    15:链表中倒数第K个节点
    14:调整数组顺序使奇数位于偶数的前面
    13:在O(1)时间内删除单向链表中的一个节点
    centos7下zookeeper集群安装部署
    zabbix3.2监控mysql
    解决关于confluence缓慢 字体乱码 宏乱码 编辑不能贴图等问题
    nginx日志文件的定时切割与归纳
    centos7安装sonarqube6.7 代码质量管理平台
    centos7下安装vnc更改vnc默认端口号
    centos7安装java环境和maven环境
  • 原文地址:https://www.cnblogs.com/xuying-fall/p/9509502.html
Copyright © 2011-2022 走看看