使用常规字符串函数及动态视图解决where in list问题(读书笔记之三)
来源:互联网 发布:饿了么数据分析 编辑:程序博客网 时间:2024/06/05 17:00
----使用常规字符串函数及动态视图
/*如果数据库版本较低,无法使用正则表达式,则使用instr\SUBSTR等函数处理指定分隔符的字符串,将字符串按分隔符转为行,这样就可以像上面那样处理
首先要解决的问题就是,如何使用instr,SUBSTR等函数将字符串按分隔符转为多行记录,比如'ab,bc,cd'这个字符串来说,要转为3行记录分别为
'ab'、'bc'、'cd',如何转换呢?一般要用到connect BY的,试想如果将字符串转为',ab,bc,cd,',那么就很好转换了,找第一个值'ab'就是从
第一个逗号后面的位置开始,然后截取的长度就是第2个逗号位置减去第一个逗号位置再减去1,其他值类似,有了这个分析,就能很好的实现这个需求了:*/
/*instr函数:返回要截取的字符串在源字符串中的位置,语法如下:
instr( string1, string2 [, start_position [, nth_appearance ] ] )
参数分析:
string1
源字符串,要在此字符串中查找。
string2
要在string1中查找的字符串.
start_position
代表string1 的哪个位置开始查找。此参数可选,如果省略默认为1. 字符串索引从1开始。如果此参数为正,从左到右开始检索,如果此参数为负,从右到左检索,返回要查找的字符串在源字符串中的开始索引。
nth_appearance
代表要查找第几次出现的string2. 此参数可选,如果省略,默认为 1.如果为负数系统会报错。
注意:
如果String2在String1中没有找到,instr函数返回0.*/
/*有了上面的结果作为子查询就和正则表达式一样可以解决where IN LIST的问题,由于这样的子查询可能会很复杂,为了隐藏子查询的复杂性,
可以降子查询封装为一个动态视图
所谓动态视图就是传入不同的字符串,视图的结果是不同的
在pl/sql中有内置包dbms_session,这个包的方法set_context可以创建绑定名字的上下文,并且具有属性名和属性值,通过sys_context函数就可以
获取指定上下文的属性值,这样只要视图中的字符串值是通过sys_context获取的就可以了,每次调用存储过程重置context。
注意创建context必须在一个命名过程或包过程中调用dbms_session.set_context,而不能在匿名过程中直接使用dbms_session.set_context*/
首先以DBA身份赋权限:grant create any context to scott;
--创建上下文,这个上下文的名字是inlist_ctx,需要由过程set_inlist_ctx_prc创建
--建立与上下文创建相关的过程
--建立视图,创建动态视图,让sys_context动态给视图传常参数,只需要将前面语句中的绑定变量:str改为sys_context('inlist_ctx','str')就可以
--创建上下文,并给予属性str初始值为'ab,bc,cd'
--修改上下文属性值,则视图也改变
/*动态视图正常工作,而且因为保存在context内的属性是session范围内的,具有很好的并发性
接下来,用这个动态视图解决where IN LIST的问题就简单多了,只要将视图放在子查询中即可*/
使用动态视图可以隐藏查询的复杂性,只要在每次查询前调用存储过程重置context即可,这是可以在低版本数据库中适用的方法
/*如果数据库版本较低,无法使用正则表达式,则使用instr\SUBSTR等函数处理指定分隔符的字符串,将字符串按分隔符转为行,这样就可以像上面那样处理
首先要解决的问题就是,如何使用instr,SUBSTR等函数将字符串按分隔符转为多行记录,比如'ab,bc,cd'这个字符串来说,要转为3行记录分别为
'ab'、'bc'、'cd',如何转换呢?一般要用到connect BY的,试想如果将字符串转为',ab,bc,cd,',那么就很好转换了,找第一个值'ab'就是从
第一个逗号后面的位置开始,然后截取的长度就是第2个逗号位置减去第一个逗号位置再减去1,其他值类似,有了这个分析,就能很好的实现这个需求了:*/
/*instr函数:返回要截取的字符串在源字符串中的位置,语法如下:
instr( string1, string2 [, start_position [, nth_appearance ] ] )
参数分析:
string1
源字符串,要在此字符串中查找。
string2
要在string1中查找的字符串.
start_position
代表string1 的哪个位置开始查找。此参数可选,如果省略默认为1. 字符串索引从1开始。如果此参数为正,从左到右开始检索,如果此参数为负,从右到左检索,返回要查找的字符串在源字符串中的开始索引。
nth_appearance
代表要查找第几次出现的string2. 此参数可选,如果省略,默认为 1.如果为负数系统会报错。
注意:
如果String2在String1中没有找到,instr函数返回0.*/
VAR str VARCHAR2(100);EXEC :str :='ab,bc,cd';SELECT SUBSTR(inlist,INSTR(inlist,',',1,LEVEL)+1,INSTR(inlist,',',1,LEVEL+1)-INSTR(inlist,',',1,LEVEL)-1) AS value_strFROM (SELECT ','||:str||',' AS inlist FROM dual)CONNECT BY LEVEL <= LENGTH(:str)-LENGTH(REPLACE(:str,',',''))+1;
/*有了上面的结果作为子查询就和正则表达式一样可以解决where IN LIST的问题,由于这样的子查询可能会很复杂,为了隐藏子查询的复杂性,
可以降子查询封装为一个动态视图
所谓动态视图就是传入不同的字符串,视图的结果是不同的
在pl/sql中有内置包dbms_session,这个包的方法set_context可以创建绑定名字的上下文,并且具有属性名和属性值,通过sys_context函数就可以
获取指定上下文的属性值,这样只要视图中的字符串值是通过sys_context获取的就可以了,每次调用存储过程重置context。
注意创建context必须在一个命名过程或包过程中调用dbms_session.set_context,而不能在匿名过程中直接使用dbms_session.set_context*/
首先以DBA身份赋权限:grant create any context to scott;
--创建上下文,这个上下文的名字是inlist_ctx,需要由过程set_inlist_ctx_prc创建
CREATE OR REPLACE CONTEXT inlist_ctx USING set_inlist_ctx_prc;
--建立与上下文创建相关的过程
CREATE OR REPLACE PROCEDURE set_inlist_ctx_prc(p_val IN VARCHAR2)ASBEGIN dbms_session.set_context('inlist_ctx','str',p_val);END;/
--建立视图,创建动态视图,让sys_context动态给视图传常参数,只需要将前面语句中的绑定变量:str改为sys_context('inlist_ctx','str')就可以
CREATE OR REPLACE VIEW v_inlistASSELECT SUBSTR(inlist,INSTR(inlist,',',1,LEVEL)+1,INSTR(inlist,',',1,LEVEL+1)-INSTR(inlist,',',1,LEVEL)-1) AS value_strFROM (SELECT ','||sys_context('inlist_ctx','str')||',' AS inlist FROM dual)CONNECT BY LEVEL <= LENGTH(sys_context('inlist_ctx','str'))-LENGTH(REPLACE(sys_context('inlist_ctx','str'),',',''))+1;
--创建上下文,并给予属性str初始值为'ab,bc,cd'
EXEC set_inlist_ctx_prc('ab,bc,cd');SELECT value_str FROM v_inlist;
--修改上下文属性值,则视图也改变
EXEC set_inlist_ctx_prc('x,y,z');SELECT value_str FROM v_inlist;
/*动态视图正常工作,而且因为保存在context内的属性是session范围内的,具有很好的并发性
接下来,用这个动态视图解决where IN LIST的问题就简单多了,只要将视图放在子查询中即可*/
EXEC set_inlist('XY,YZ');SELECT COUNT(*) FROM T1 WHERE OBJECT_NAME IN (SELECT value_str FROM v_inlist);
使用动态视图可以隐藏查询的复杂性,只要在每次查询前调用存储过程重置context即可,这是可以在低版本数据库中适用的方法
0 0
- 使用常规字符串函数及动态视图解决where in list问题(读书笔记之三)
- 静态SQL和动态SQL之where in list问题(读书笔记之一)
- 正则表达式regexp_substr解决where in list问题(读书笔记之二)
- 解决where in list问题(续)
- where in list问题
- where 函数问题引起执行计划改变(复杂视图)
- WHERE IN LIST问题解析 –丁俊
- MySQL第二天--where条件查询、视图及函数
- MySQL第二天--where条件查询、视图及函数
- SQL之解决where 1=1 问题及优化多条件查询
- OJ 之常规练习题(三)
- Java动态 遍历List 时删除List特征元素 异常问题 及解决方式总结
- 《Thinking in Java》读书笔记之并发(三)
- oracle instr应用,解决where in排序问题
- TP 框架解决Unknown column 'XXX' in 'where clause' 问题
- 读书笔记三--- Date构造函数与字符串
- Mysql where in中的参数传入字符串(字符串拼接)
- mybatis的动态SQL(三)where、set、trim标签的使用
- find . -name "*.php" -exec iconv -f ISO-8859-1 -t UTF-8 {} -o ../newdir_utf8/{} \; Batch convert fil
- 正则表达式regexp_substr解决where in list问题(读书笔记之二)
- 动态调整UITableViewCell高度的实现方法
- ios开发self的用法
- Tomcat学习笔记--启动成功访问报404错误
- 使用常规字符串函数及动态视图解决where in list问题(读书笔记之三)
- Hbase简介
- loadView和viewDidLoad,即view的生命周期浅析
- JAVA WEB开发中处理乱码汇总
- Java泛型总结
- 获得软件版本信息
- 【Unity3D】Shader Forge 节点帮助
- HDU 3974 Assign the task(dfs时间戳+线段树成段更新)
- WAS集群系列(7):集群搭建:步骤5:WAS补丁安装