Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PL/SQL:循环%ROWTYPE中的属性_Sql_Oracle_Stored Procedures_Plsql - Fatal编程技术网

PL/SQL:循环%ROWTYPE中的属性

PL/SQL:循环%ROWTYPE中的属性,sql,oracle,stored-procedures,plsql,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 ro

我在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 developer在其中加载了Excel工作表,而不使用标题

从这里开始,我尝试使用一个存储过程,通过游标在表中循环,在第1列中找到值“User”,循环该行中的属性,并将这些属性添加到roles表中,等等

但是,我在遍历每个%ROWTYPE中游标内的属性时遇到问题


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

这就是我要做的。我在这里选择一个通用版本,因为您没有提到您正在使用的Oracle版本。如果您使用的是11g或更高版本,则可以使用UNPIVOT命令执行取消激励:

我的示例insert语句的设置:

插入角色:

插入用户角色:

这两条语句都将列解压到行中,然后在插入值之前选择相关值


不需要循环或任何东西。

这是一个特别的过程,还是一个经常运行的过程?如果是后者,角色的数量会有所不同吗?@Boneist,角色的数量将是相当固定的,但是我现在有大约40个角色。多久运行一次?一次性的?每周的每日的更频繁?@Boneist,可能每两周一次,角色将基本相同,即不会改变,您使用的Oracle版本是什么?谢谢@Boneist,我必须消化一下,然后再回复您:
Column1 Column2 Column3 Column4
User    Role1   Role2   Role3
Jon     Y       Y
Mary            Y       Y
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;