ORACLE中如何实现此类条件匹配?

白头陀 2018-09-29 03:45:33
现在有这样需求:
表里两个字段,如下:

create table T1
(
a1 VARCHAR2(400),
a2 VARCHAR2(100),
a3 CHAR(1)
);

插入数据用 test window,否则有系统字符(&变量符合)无法插入,代码为:
----------------------------------------------------------test 窗口执行开始-------------------
declare
i integer;
begin
declare
i integer;
begin
insert into T1
SELECT '0A0&0B0&0DM&0F3&1A8' A1,
'0A0&0B0&0DM' A2 , 1 A3
FROM DUAL
UNION ALL
SELECT '0A0&0B0&0DM&0F3&1A8' A1,
'0A0&0B0&(0DM)' A2,2 A3
FROM DUAL
UNION ALL
SELECT '0A0&0B0&0DM&0F3&1A8' A1,
'0A0&0B0&(0F3|OX5)' A2,3 A3
FROM DUAL
UNION ALL
SELECT '0A0&0B0&0DM&0F3&1A8' A1,
'0A0&(!OX5)' A2,4 A3
FROM DUAL
UNION ALL
SELECT '0A0&0B0&0DM&0F3&1A8' A1,
'9E1&OBO&(7KA7|A77K)' A2,5 A3
FROM DUAL;
end;
------------------------------------------------------------------------

想实现如下目标:
1 表T1中列A1包含列A2的关系,则认为符合条件。
2 表中列A2 中内容包括 以下分隔符:
2.1 & 表示并列前后字符串分割开,每个必须都在列A1,则算满足。例如 ,A1='0A0&0B0&0DM', A2='OAO&ODM',则认为
符合条件;
2.2 ! 表示非的意思,例如 ,A1='0A0&0B0&0DM', A2='!123',表示满足;
2.3 |表示或,例如 ,A1='0A0&0B0&0DM', A2='OAO&(ODM|123)',表示满足;
2.4()表示逻辑运算符,优先级

哪位高手有个效率高的方法,求助,我现在写了一个解析,效率比较低。
我的思路是: 把列A2中的分隔符分别判断,然后硬解析。

有谁帮帮我,困扰好几天了,多谢
...全文
467 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
白头陀 2018-10-15
  • 打赏
  • 举报
回复
我要把分数给三楼的大神,不会操作
白头陀 2018-10-15
  • 打赏
  • 举报
回复
感谢三楼高手,加我QQ帮我调试,好人一生平安
超叔csdn 2018-10-12
  • 打赏
  • 举报
回复
对于插入时&负号会解析为变量的问题,楼上已经给出了答案。
在plsql或者sqlplus下设置命令set define off;

对于你提出的逻辑问题,确实是可以将这些符号和括号转化为oracle中的and or not () 等关键字,相应的字段做一个instr去查询存不存在应该不麻烦。
你的硬解析也是这样的思路吗?
帮你写了个函数:

create or replace function str_find(in_str1 varchar2,in_str2 varchar2)
return varchar2 as
--元素个数
ele_cnt number(10):=regexp_count(in_str2,'[[:alnum:]]+');
--符号个数
opr_cnt number(10):=regexp_count(in_str2,'[^[:alnum:]]+');
mid_opr_str varchar2(4000);
mid_ele_str varchar2(4000);
logic_str varchar2(30000);
begin
--有4种情况元素个数比操作符个数多1'a&b';元素个数比操作符个数少1'(a)';元素与操作符个数一样,元素开头'a(b)';元素与操作符个数一样,符号开头'!a'
if ele_cnt>opr_cnt or ele_cnt=opr_cnt and substr(in_str2,1,1) not in ('|','&','!','(',')') then
for i in 1..ele_cnt loop
mid_ele_str:='instr('''||in_str1||''','''||regexp_substr(in_str2,'[[:alnum:]]+',1,i)||''')>0';
mid_opr_str:=replace(replace(replace(regexp_substr(in_str2,'[^[:alnum:]]+',1,i),'!',' not '),'&',' and '),'|',' or ');
logic_str:=logic_str||mid_ele_str||mid_opr_str;
end loop;
else
for i in 1..opr_cnt loop
mid_ele_str:='instr('''||in_str1||''','''||regexp_substr(in_str2,'[[:alnum:]]+',1,i)||''')>0';
mid_opr_str:=replace(replace(replace(regexp_substr(in_str2,'[^[:alnum:]]+',1,i),'!',' not '),'&',' and '),'|',' or ');
logic_str:=logic_str||mid_opr_str||mid_ele_str;
end loop;
end if;

return logic_str;
end;
卖水果的net 2018-10-12
  • 打赏
  • 举报
回复

SQL> set define off;

白头陀 2018-09-29
  • 打赏
  • 举报
回复
不知道我说明白没有,没看懂的老师加我一下QQ:56693122,在线等,非常感谢

17,086

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧