2017-02-23 5 views
0

カーソルを使用してSQL Serverの同等のコードをPLSQLの同等のコードに更新するにはどうすればよいですか? SQL Serverでのその後カーソルを使用して一時テーブルを使用してSQL ServerからOracle PLSQLにコードを変換します。

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; 

一時テーブルを使用すると、以下が行われます:

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) 

どのようにすることができ、私は次のようなものを持っているPL/SQLで

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  

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から」私はエラーを取得する「テーブルまたはビューが存在しません」をやろうとしています。

+0

まず、SQL Serverには一時テーブルはありません。あなたはテーブルとして宣言された変数を持っています。そして、なぜあなたはCURSORを使って同じことをする必要がありますか?これの目的は何ですか?あなたは単にOracleで一時テーブルを使用できませんか? – asemprini87

答えて

0

カーソルをテーブルのように照会することはできません。彼らはまったく違うものです。カーソルでできるのは、開いてフェッチして閉じることだけです。

結果を2か所で使用する必要があるため、global temporary tableを作成する価値があります。定義は通常のテーブルのように永続的であるため、これを個別に定義する必要があります。これは、セッションにプライベートな内容だけです。

また、バルク・フェッチコレクションに結果をして、この問題のように2つのforall文、使用になります(この例では唯一の問題は、周りfor update句を追加しました

bulk collect using "for update"

をこれは無視することができます)。

関連する問題