使用Cursor将使用临时表的SQL SERVER代码转换为Oracle PLSQL

时间:2017-02-23 18:34:42

标签: sql-server plsql

如何使用游标将临时表转换为在SQL Server中使用等效代码进行更新?

ALTER proc [dbo].[sp_lista] (@pcFI datetime, @pcFF datetime, @vSuma tinyint) as
    begin tran

    Declare @crLista Table (
        NEnt int,
        NEje int,
        NExp char(17),
        NAcu char(17),
        NSen char(17)
     )

     if @vSuma = 0
         begin
             insert into @crLista 
             select tablax.num_entrada, tablax.ejercicio,                                               tablax.num_expediente, tablax.num_acuerdo, tablax.num_sentencia,    tablax.descripcion
             from   tablax inner join tablaz on
                    tablaz.num_expediente = tablax.num_expediente
             where  tablax.est_suma = 0 and (EXISTS
                    ( SELECT 1
                      FROM   tablay
                      WHERE  tablay.cve_usuario = SESSION_USER
                      and    tablay.cve_region = tablaz.cve_region
                      and    tablay.cve_sala = tablaz.cve_sala
                      and    tablay.cve_mag = tablaz.cve_mag
                      and    tablay.cve_srio = tablaz.cve_srio) )

         update tablax 
                set notificado = 1,
                fec_notificado = getdate()
         from   @crLista MLista
         where  MLista.NEnt = tablax.num_entrada and
                MLista.NEje = tablax.ejercicio and tablax.est_suma = @vSuma     

在PL / SQL中,我有以下内容:

create or replace PROCEDURE sp_lista(
    v_pcFI IN DATE,
    v_pcFF   IN DATE,
    v_vSuma  IN NUMBER
)
AS
    vcMLista SYS_REFCURSOR;
BEGIN
    IF v_vSuma = 0 THEN
        BEGIN
            open vcMLista for
                SELECT tablax.num_entrada ,
                       tablax.ejercicio ,
                       tablax.num_expediente ,
                       tablax.num_acuerdo ,
                       tablax.num_sentencia
                FROM   tablax
                       JOIN tablaz
                       ON   tablaz.num_expediente = tablax.num_expediente
                WHERE  tablax.est_suma = 0
                AND    ( EXISTS
                         ( SELECT 1
                           FROM   tablay
                           WHERE  tablay.cve_usuario  = v_vcUsr_actual
                           AND    tablay.cve_region   =  tablaz.cve_region
                           AND    tablay.cve_sala     = tablaz.cve_sala
                           AND    tablay.cve_mag      = tablaz.cve_mag
                           AND    tablay.cve_srio     = tablaz.cve_srio
                         ) )
                FOR UPDATE;

随后在SQL SERVER中使用临时表,并完成以下操作:

update tablax 
       set notificado = 1,
       fec_notificado = getdate()
from   @crLista MLista
where  MLista.NEnt = tablax.num_entrada and
       MLista.NEje = tablax.ejercicio and tablax.est_suma = @vSuma

update tablay set fmod =getdate()
where  ndoc in 
       ( select distinct NExp from @crLista )

如何使用游标执行PLSQL等效操作?我尝试了以下内容:

OPEN crLista;
FETCH crLista INTO reg;

WHILE crLista%FOUND LOOP
    UPDATE actm_lista SET  
           notificado = 1,
           FEC_NOTIFICADO = sysdate
    WHERE  CURRENT OF crLista;

    FETCH crLista INTO reg;
END LOOP;

OPEN crLista;
FETCH crLista INTO reg;

WHILE crLista%FOUND LOOP  
    UPDATE tablax
    SET    fmod = SYSDATE
    WHERE  ne IN
           ( SELECT DISTINCT reg.ne FROM crLista );

    FETCH crLista INTO reg;
END LOOP;    

UPDATE tablay
SET    fmod = SYSDATE
WHERE  ndoc IN
       ( SELECT DISTINCT ndoc FROM crLista );

但是当尝试“从crLista”执行时,我收到错误“表或视图不存在”。

1 个答案:

答案 0 :(得分:0)

您无法将游标视为表格。它们是完全不同的东西。光标的所有功能都是打开,获取和关闭。

由于您需要在两个地方使用结果,因此可能值得创建global temporary table。你必须单独定义它,因为定义像普通表一样是永久性的 - 它只是会话专用的内容。

您还可以查看将结果批量提取到集合中并使用两个forall语句,如下所示:

bulk collect using "for update"

(在该示例中,唯一的问题是添加for update子句,您可以忽略它。)