循环的最后一次迭代没有从select语句中获取计数

时间:2015-08-26 13:19:25

标签: oracle plsql oracle11g

我有一个表,我从中选择数据然后检查从另一个表中获取的数据是否存在然后将执行其他操作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位生产

1 个答案:

答案 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.