我有一个表,我从中选择数据然后检查从另一个表中获取的数据是否存在然后将执行其他操作null;
create table cmts_data (cmts_token varchar2(30), IP varchar2(20));
insert into cmts_data values ('wnlb-cmts-01-1','10.15.0.1');
insert into cmts_data values ('wnlb-cmts-02-2','10.15.0.2');
insert into cmts_data values ('wnlb-cmts-03-3','10.15.0.3');
insert into cmts_data values ('wnlb-cmts-04-4','10.15.0.4');
insert into cmts_data values ('wnlb-cmts-05-5','10.15.0.5');
我从中选择数据的另一个表 -
create table link_data (dhcp_token varchar2(30), cmts_to_add varchar2(200), cmts_to_remove varchar2(200));
insert into link_data values ('dhcp-1-1-1','wnlb-cmts-01-1,wnlb-cmts-02-2', null);
insert into link_data values ('dhcp-1-1-2','wnlb-cmts-03-3,wnlb-cmts-04-4,wnlb-cmts-05-5', null);
insert into link_data values ('dhcp-1-1-3','wnlb-cmts-01-1', null);
insert into link_data values ('dhcp-1-1-4','wnlb-cmts-05-8,wnlb-cmts-05-6,wnlb-cmts-05-0,wnlb-cmts-03-3', null);
insert into link_data values ('dhcp-1-1-5','wnlb-cmts-02-2,wnlb-cmts-04-4,wnlb-cmts-05-7', null);
create table subntwk (subntwk_nm varchar2(30));
insert into subntwk values ('dhcp-1-1-1');
insert into subntwk values ('dhcp-1-1-2');
insert into subntwk values ('dhcp-1-1-3');
insert into subntwk values ('dhcp-1-1-4');
insert into subntwk values ('dhcp-1-1-5');
这两个表的结构和样本数据
现在我有了这个PLSQL块 -
DECLARE
l_cmts VARCHAR2( 200 CHAR );
l_cmts_1 VARCHAR2( 200 CHAR );
l_dhcp_cnt number;
l_cmts_cnt number;
BEGIN
FOR r IN ( SELECT dhcp_token, cmts_to_add || ',' cmts
FROM link_data
)
LOOP
l_cmts := r.cmts;
l_cmts_1 := trim(SUBSTR( l_cmts, 1, INSTR(l_cmts, ',' ) - 1 ));
dbms_output.put_line(r.dhcp_token);
select count(1) into l_dhcp_cnt from subntwk where subntwk_nm = r.dhcp_token;
DBMS_OUTPUT.PUT_LINE(l_dhcp_cnt );
-- WHILE l_cmts_1 IS NOT NULL
LOOP
--DBMS_OUTPUT.PUT_LINE( r.dhcp_token || '|' || l_cmts_1 );
dbms_output.put_line(l_cmts_1);
select count(1) into l_cmts_cnt from cmts_data where trim(cmts_token) = trim(l_cmts_1);
DBMS_OUTPUT.PUT_LINE(l_cmts_cnt);
/*
if l_dhcp_cnt >0 and l_cmts_cnt > 0 then
DBMS_OUTPUT.PUT_LINE( r.dhcp_token || '|' || l_cmts_1 );
end if;
*/
l_cmts := trim(SUBSTR( l_cmts, INSTR( l_cmts, ',' ) + 1 ));
l_cmts_1 := trim(SUBSTR( l_cmts, 1, INSTR( l_cmts, ',' ) - 1 ));
exit when l_cmts_1 is null;
END LOOP;
END LOOP;
END;
此块的DBMS_OUTPUT是---
dhcp-1-1-1
1
wnlb-cmts-01-1
1
wnlb-cmts-02-2
0
dhcp-1-1-2
1
wnlb-cmts-03-3
1
wnlb-cmts-04-4
1
wnlb-cmts-05-5
0
dhcp-1-1-3
1
wnlb-cmts-01-1
0
dhcp-1-1-4
1
wnlb-cmts-05-8
0
wnlb-cmts-05-6
0
wnlb-cmts-05-0
0
wnlb-cmts-03-3
0
dhcp-1-1-5
1
wnlb-cmts-02-2
1
wnlb-cmts-04-4
1
wnlb-cmts-05-7
0
预期输出 -
dhcp-1-1-1
1
wnlb-cmts-01-1
1
wnlb-cmts-02-2
1
dhcp-1-1-2
1
wnlb-cmts-03-3
1
wnlb-cmts-04-4
1
wnlb-cmts-05-5
1
dhcp-1-1-3
1
wnlb-cmts-01-1
1
dhcp-1-1-4
1
wnlb-cmts-05-8
0
wnlb-cmts-05-6
0
wnlb-cmts-05-0
0
wnlb-cmts-03-3
1
dhcp-1-1-5
1
wnlb-cmts-02-2
1
wnlb-cmts-04-4
1
wnlb-cmts-05-7
0
在这里我们可以看到,在内部循环的每个最后一次迭代中,它给出了l_cmts_1名称,但是为什么最后一个l_cmts_1的计数为0。
这里我也放了一些不存在的值,因为它可以在我的场景中因为我得到0这很好但是我看到的这个PLSQL块的behaiour是内部循环它给出了变量的名称但是select语句(用于计数)不接受它!
我试图将该select语句放在块中的不同位置,但没有一个正在工作。
我试过的SQL ---
with link_data_expand
as
(
select dhcp_token
, regexp_substr(cmts_to_add, '[^,]+', 1, level) cmts_to_add
from link_data
connect
by level <= length(cmts_to_add) - length(replace(cmts_to_add, ',')) + 1
and prior dhcp_token = dhcp_token
and prior dbms_random.value() is not null
)
select a.dhcp_token
, a.cmts_to_add
, count(b.cmts_token) cnt
from link_data_expand a
left join
cmts_data b
on a.cmts_to_add = b.cmts_token
group
by a.dhcp_token
, a.cmts_to_add
order
by a.dhcp_token
, a.cmts_to_add;
SQL的结果 -
DHCP_TOKEN CMTS_TO_ADD CNT
dhcp-1-1-1 wnlb-cmts-01-1 1
dhcp-1-1-1 wnlb-cmts-02-2 0
dhcp-1-1-2 wnlb-cmts-03-3 1
dhcp-1-1-2 wnlb-cmts-04-4 1
dhcp-1-1-2 wnlb-cmts-05-5 0
dhcp-1-1-3 wnlb-cmts-01-1 0
dhcp-1-1-4 wnlb-cmts-03-3 0
dhcp-1-1-4 wnlb-cmts-05-0 0
dhcp-1-1-4 wnlb-cmts-05-6 0
dhcp-1-1-4 wnlb-cmts-05-8 0
dhcp-1-1-5 wnlb-cmts-02-2 1
dhcp-1-1-5 wnlb-cmts-04-4 1
dhcp-1-1-5 wnlb-cmts-05-7 0
任何建议我在这里做错了什么!
数据库版本 -
Oracle Database 11g企业版11.2.0.1.0版 - 64位生产
答案 0 :(得分:0)
根据您在上述评论中提出的内容,我相信以下问题可以为您提供所需内容:
with link_info as (select dhcp_token,
cmts_to_add,
cmts_to_remove,
trim(regexp_substr(cmts_to_add, '[^,]+', 1, level)) sub_cmt_to_add
from link_data
connect by prior dhcp_token = dhcp_token
and prior dbms_random.value is not null
and level <= regexp_count(cmts_to_add, ',') + 1)
select li.dhcp_token,
sn.subntwk_nm,
li.sub_cmt_to_add,
trim(cd.cmts_token) cmts_token,
cd.ip
from link_info li
left outer join cmts_data cd on (li.sub_cmt_to_add = trim(cd.cmts_token))
left outer join subntwk sn on (li.dhcp_token = sn.subntwk_nm);
DHCP_TOKEN SUBNTWK_NM SUB_CMT_TO_ADD CMTS_TOKEN IP
---------- ---------- --------------- --------------- ----------
dhcp-1-1-1 dhcp-1-1-1 wnlb-cmts-02-2 wnlb-cmts-02-2 10.15.0.2
dhcp-1-1-1 dhcp-1-1-1 wnlb-cmts-01-1 wnlb-cmts-01-1 10.15.0.1
dhcp-1-1-2 dhcp-1-1-2 wnlb-cmts-05-5 wnlb-cmts-05-5 10.15.0.5
dhcp-1-1-2 dhcp-1-1-2 wnlb-cmts-04-4 wnlb-cmts-04-4 10.15.0.4
dhcp-1-1-2 dhcp-1-1-2 wnlb-cmts-03-3 wnlb-cmts-03-3 10.15.0.3
dhcp-1-1-3 dhcp-1-1-3 wnlb-cmts-01-1 wnlb-cmts-01-1 10.15.0.1
dhcp-1-1-4 dhcp-1-1-4 wnlb-cmts-05-0
dhcp-1-1-4 dhcp-1-1-4 wnlb-cmts-05-6
dhcp-1-1-4 dhcp-1-1-4 wnlb-cmts-05-8
dhcp-1-1-4 dhcp-1-1-4 wnlb-cmts-03-3 wnlb-cmts-03-3 10.15.0.3
dhcp-1-1-5 dhcp-1-1-5 wnlb-cmts-05-7
dhcp-1-1-5 dhcp-1-1-5 wnlb-cmts-04-4 wnlb-cmts-04-4 10.15.0.4
dhcp-1-1-5 dhcp-1-1-5 wnlb-cmts-02-2 wnlb-cmts-02-2 10.15.0.2
在sql语句中使用数据的优点是,您可以根据需要将其插入INSERT / MERGE / UPDATE语句以进行必要的修改。
关于你的问题,我不知道为什么你会看到每个dhcp_token的最后一次迭代的0个计数。我运行了你的确切的创建表/插入语句/匿名块并获得了预期的结果(尽管我在插入语句的末尾添加了一个提交)。
这是我作为脚本运行的(在Toad中):
drop table cmts_data;
drop table link_data;
drop table subntwk;
create table cmts_data (cmts_token varchar2(30), IP varchar2(20));
insert into cmts_data values ('wnlb-cmts-01-1','10.15.0.1');
insert into cmts_data values ('wnlb-cmts-02-2','10.15.0.2');
insert into cmts_data values ('wnlb-cmts-03-3','10.15.0.3');
insert into cmts_data values ('wnlb-cmts-04-4','10.15.0.4');
insert into cmts_data values ('wnlb-cmts-05-5','10.15.0.5');
create table link_data (dhcp_token varchar2(30), cmts_to_add varchar2(200), cmts_to_remove varchar2(200));
insert into link_data values ('dhcp-1-1-1','wnlb-cmts-01-1,wnlb-cmts-02-2', null);
insert into link_data values ('dhcp-1-1-2','wnlb-cmts-03-3,wnlb-cmts-04-4,wnlb-cmts-05-5', null);
insert into link_data values ('dhcp-1-1-3','wnlb-cmts-01-1', null);
insert into link_data values ('dhcp-1-1-4','wnlb-cmts-05-8,wnlb-cmts-05-6,wnlb-cmts-05-0,wnlb-cmts-03-3', null);
insert into link_data values ('dhcp-1-1-5','wnlb-cmts-02-2,wnlb-cmts-04-4,wnlb-cmts-05-7', null);
create table subntwk (subntwk_nm varchar2(30));
insert into subntwk values ('dhcp-1-1-1');
insert into subntwk values ('dhcp-1-1-2');
insert into subntwk values ('dhcp-1-1-3');
insert into subntwk values ('dhcp-1-1-4');
insert into subntwk values ('dhcp-1-1-5');
commit;
set serveroutput on;
DECLARE
l_cmts VARCHAR2( 200 CHAR );
l_cmts_1 VARCHAR2( 200 CHAR );
l_dhcp_cnt number;
l_cmts_cnt number;
BEGIN
FOR r IN ( SELECT dhcp_token, cmts_to_add || ',' cmts
FROM link_data
)
LOOP
l_cmts := r.cmts;
l_cmts_1 := trim(SUBSTR( l_cmts, 1, INSTR(l_cmts, ',' ) - 1 ));
dbms_output.put_line(r.dhcp_token);
select count(1) into l_dhcp_cnt from subntwk where subntwk_nm = r.dhcp_token;
DBMS_OUTPUT.PUT_LINE(l_dhcp_cnt );
-- WHILE l_cmts_1 IS NOT NULL
LOOP
--DBMS_OUTPUT.PUT_LINE( r.dhcp_token || '|' || l_cmts_1 );
dbms_output.put_line(l_cmts_1);
select count(1) into l_cmts_cnt from cmts_data where trim(cmts_token) = trim(l_cmts_1);
DBMS_OUTPUT.PUT_LINE(l_cmts_cnt);
/*
if l_dhcp_cnt >0 and l_cmts_cnt > 0 then
DBMS_OUTPUT.PUT_LINE( r.dhcp_token || '|' || l_cmts_1 );
end if;
*/
l_cmts := trim(SUBSTR( l_cmts, INSTR( l_cmts, ',' ) + 1 ));
l_cmts_1 := trim(SUBSTR( l_cmts, 1, INSTR( l_cmts, ',' ) - 1 ));
exit when l_cmts_1 is null;
END LOOP;
END LOOP;
END;
/
这是我得到的输出:
Table dropped.
Table dropped.
Table dropped.
Table created.
1 row created.
1 row created.
1 row created.
1 row created.
1 row created.
Table created.
1 row created.
1 row created.
1 row created.
1 row created.
1 row created.
Table created.
1 row created.
1 row created.
1 row created.
1 row created.
1 row created.
Commit complete.
dhcp-1-1-1
1
wnlb-cmts-01-1
1
wnlb-cmts-02-2
1
dhcp-1-1-2
1
wnlb-cmts-03-3
1
wnlb-cmts-04-4
1
wnlb-cmts-05-5
1
dhcp-1-1-3
1
wnlb-cmts-01-1
1
dhcp-1-1-4
1
wnlb-cmts-05-8
0
wnlb-cmts-05-6
0
wnlb-cmts-05-0
0
wnlb-cmts-03-3
1
dhcp-1-1-5
1
wnlb-cmts-02-2
1
wnlb-cmts-04-4
1
wnlb-cmts-05-7
0
PL/SQL procedure successfully completed.