PL / SQL:循环遍历%ROWTYPE

时间:2016-04-04 15:33:45

标签: sql oracle stored-procedures plsql

我在excel中有一个矩阵,在第一列中我有用户名,在第二列和后续列中我有角色名称和一个' Y'如果用户是角色的成员:

User Role1 Role2 Role3
Jon   Y      Y
Mary         Y    Y

我需要将其加载到Oracle数据库中。在数据库中,我已经有一个用户表:

UserId Username
1        Jon
2        Mary

我需要扮演角色,即Role1,Role2,Role3并将其加载到角色表中:

roleId role
1      Role1
2      Role2
3      Role3

然后我需要将角色成员资格加载到角色映射表中:

UserId RoleId
1      1
1      2
2      2
2      3

到目前为止,我创建了一个包含Column1,Column2,Column3属性的表,并使用SQL开发人员在其中加载Excel工作表,而不使用 HEADER

Column1 Column2 Column3 Column4
User    Role1   Role2   Role3
Jon     Y       Y
Mary            Y       Y

从这里开始我尝试使用存储过程用光标遍历表格,并在其中找到值' User'在Column1中,循环遍历该行中的属性并将其添加到角色表等

但是我在每个%ROWTYPE中循环浏览CURSOR中的属性时遇到了问题。

这是一个好方法吗?如何遍历%ROWTYPE中的每个属性?

1 个答案:

答案 0 :(得分:2)

这就是我要做的事情(我在这里推广通用版本,因为你没有提到你正在使用的Oracle版本。如果你正在使用的话。\ n \ n 11g或更高版本,你可以使用UNPIVOT命令进行解锁):

我的示例插入语句的设置:

create table data_to_upload as
select 'User' col1, 'Role1' col2, 'Role2' col3, 'Role3' col4 from dual union all
select 'Jon' col1, 'Y' col2, 'Y' col3, null col4 from dual union all
select 'Mary' col1, null col2, 'Y' col3, 'Y' col4 from dual;

create table test_users as
select 1 userid, 'Jon' username from dual union all
select 2 userid, 'Mary' username from dual;

create table test_roles (roleid number,
                         rolename varchar2(20));

create sequence test_roles_seq
  start with 1
  maxvalue 9999
  minvalue 1
  nocycle
  cache 20;

create table test_user_roles (userid number, roleid number);

插入角色:

insert into test_roles
select test_roles_seq.nextval roleid,
       case when dummy.id = 1 then (select col2 from data_to_upload where col1 = 'User')
            when dummy.id = 2 then (select col3 from data_to_upload where col1 = 'User')
            when dummy.id = 3 then (select col4 from data_to_upload where col1 = 'User')
       end rolename
from   data_to_upload dto
       cross join (select level id
                   from   dual
                   connect by level <= 3 -- number of roles being imported
                  ) dummy
where col1 = 'User';

commit;

插入用户角色:

insert into test_user_roles
select tu.userid,
       case when dummy.id = 1 then (select tr.roleid from data_to_upload dtu2 inner join test_roles tr on (dtu2.col2 = tr.rolename) where dtu2.col1 = 'User')
            when dummy.id = 2 then (select tr.roleid from data_to_upload dtu2 inner join test_roles tr on (dtu2.col3 = tr.rolename) where dtu2.col1 = 'User')
            when dummy.id = 3 then (select tr.roleid from data_to_upload dtu2 inner join test_roles tr on (dtu2.col4 = tr.rolename) where dtu2.col1 = 'User')
       end roleid
from   data_to_upload dtu
       inner join test_users tu on (dtu.col1 = tu.username)
       inner join (select level id
                   from   dual
                   connect by level <= 3 -- number of roles being imported
                  ) dummy on ((dummy.id = 1 and dtu.col2 = 'Y')
                              or (dummy.id = 2 and dtu.col3 = 'Y')
                              or (dummy.id = 3 and dtu.col4 = 'Y'))
where col1 != 'User';

commit;

两个语句都将列拆分为行,然后在插入值之前选择相关值。

不需要循环或任何东西。