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%原创!且读且学习。
  • 相关阅读:
    js对象数组(JSON) 根据某个共同字段 分组
    一个 函数 用来转化esSearch 的range 条件
    关于 vuex 报错 Do not mutate vuex store state outside mutation handlers.
    android listview 重用view导致的选择混乱问题
    android SDK和ADT的更新
    Android中adb push和adb install的使用区别
    pycharm中添加扩展工具pylint
    su Authentication failure解决
    Putty以及adb网络调试
    有关android源码编译的几个问题
  • 原文地址:https://www.cnblogs.com/xuying-fall/p/9509502.html
Copyright © 2011-2022 走看看