ORACLE PL SQL:选择全部并处理每个记录

ORACLE PL SQL:选择全部并处理每个记录,oracle,plsql,Oracle,Plsql,我想听听你对如何实现plsql的建议。下面是我想做的情况 从表A中选择* 循环-从1个步骤中获取每个记录,并执行存储过程,处理mea.field1、a.field2、a.field3 | | test、a.field4 我不知道如何实现这样的东西。下面是processMe的示例参数 processMe( number_name IN VARCHAR, location IN VARCHAR, name_test IN VARCHAR, gender IN VAR

我想听听你对如何实现plsql的建议。下面是我想做的情况

从表A中选择*

循环-从1个步骤中获取每个记录,并执行存储过程,处理mea.field1、a.field2、a.field3 | | test、a.field4

我不知道如何实现这样的东西。下面是processMe的示例参数

processMe(
    number_name IN VARCHAR, 
    location IN VARCHAR,
    name_test IN VARCHAR,
    gender IN VARCHAR )
Begin 
   select objId into obj_Id from tableUser where name = number_name ;
   select locId into loc_Id from tableLoc where loc = location;
   insert into tableOther(obj_id,loc_id,name_test,gender) 
      values (obj_Id ,loc_Id, name_test, gender)
End;
照你说的做。您可能希望在选择列表中显式列出您实际需要的列,而不是执行SELECT*操作,特别是如果您实际需要的四列上有一个索引,可以使用该索引而不是执行表扫描,或者如果您不需要包含大量数据的列。根据数据量的不同,如果定义一个可以接受集合的processMe版本,而不是在逐行的基础上处理数据,那么效率可能会更高


照你说的做。您可能希望在选择列表中显式列出您实际需要的列,而不是执行SELECT*操作,特别是如果您实际需要的四列上有一个索引,可以使用该索引而不是执行表扫描,或者如果您不需要包含大量数据的列。根据数据量的不同,如果定义的processMe版本可以接受集合,而不是逐行处理数据,则效率可能会更高。

您可以使用使用游标行类型声明的变量。大概是这样的:

declare

cursor my_cursor is
  select * from table;

reg my_cursor%rowtype;

begin 
  for reg in my_cursor loop
    --
    processMe(reg.field1, reg.field2, reg.field3 || "test", reg.field4);
    --
  end loop;
end;

可以使用使用游标行类型声明的变量。大概是这样的:

declare

cursor my_cursor is
  select * from table;

reg my_cursor%rowtype;

begin 
  for reg in my_cursor loop
    --
    processMe(reg.field1, reg.field2, reg.field3 || "test", reg.field4);
    --
  end loop;
end;

我只是添加了一些过程。但这只是一个样本。顺便问一下,为什么 你说使用循环不是个好主意?我很想知道

在性能方面,如果您可以避免在循环中执行其他DML的结果集中循环,那么就这样做

有PL/SQL引擎,也有SQL引擎。每当PL/SQL引擎偶然发现一条SQL语句时,无论它是select、insert还是任何其他DML语句,它都必须将其发送到SQL引擎执行。它称为上下文切换。如果有多个DML语句,则将DML语句放置在循环中会导致每个DML语句的切换次数与循环体的执行次数相同。这可能会导致性能严重下降。如果必须循环,比如说,通过集合,使用foreach循环,它可以通过成批执行DML语句来最小化上下文切换

幸运的是,您的代码可以重写为单个SQL语句,从而完全避免了for循环:

insert into tableOther(obj_id,loc_id,name_test,gender) 
    select tu.objId
         , tl.locid
         , concat(a.field3, 'test')
         , a.field4                       
      from table a
      join tableUser tu
        on (a.field1 = tu.name)
      join tableLoc tl
        on (tu.field2 = tl.loc)
如果需要,可以将insert语句放入过程中。PL/SQL无论如何都必须将此SQL语句发送到SQL引擎,但只需一次调用


我只是添加了一些过程。但这只是一个样本。顺便问一下,为什么 你说使用循环不是个好主意?我很想知道

在性能方面,如果您可以避免在循环中执行其他DML的结果集中循环,那么就这样做

有PL/SQL引擎,也有SQL引擎。每当PL/SQL引擎偶然发现一条SQL语句时,无论它是select、insert还是任何其他DML语句,它都必须将其发送到SQL引擎执行。它称为上下文切换。如果有多个DML语句,则将DML语句放置在循环中会导致每个DML语句的切换次数与循环体的执行次数相同。这可能会导致性能严重下降。如果必须循环,比如说,通过集合,使用foreach循环,它可以通过成批执行DML语句来最小化上下文切换

幸运的是,您的代码可以重写为单个SQL语句,从而完全避免了for循环:

insert into tableOther(obj_id,loc_id,name_test,gender) 
    select tu.objId
         , tl.locid
         , concat(a.field3, 'test')
         , a.field4                       
      from table a
      join tableUser tu
        on (a.field1 = tu.name)
      join tableLoc tl
        on (tu.field2 = tl.loc)

如果需要,可以将insert语句放入过程中。PL/SQL无论如何都必须将此SQL语句发送到SQL引擎,但只需一次调用。

通常,在循环中逐行处理不是一个好主意。processMe存储过程到底是做什么的?我只是添加了一些进程。但这只是一个样本。顺便问一下,为什么你说使用循环不是一个好主意?我想知道..在循环中逐行处理通常不是一个好主意。processMe存储过程到底是做什么的?我只是添加了一些进程。但这只是一个样本。顺便问一下,为什么你说使用循环不是一个好主意?我想知道。。