1

私のストアドプロシージャは次のようになります。

  sqlQuery := 'DROP INDEX idArchivoIndex';
  EXECUTE IMMEDIATE sqlQuery;

  EXCEPTION --En caso de que no exista el índice capturamos la excepcion
    WHEN index_not_exists THEN NULL; --y la ignoramos

  sqlQuery := 'CREATE INDEX idArchivoIndex'||
              ' ON '||qusuario||' (id_archivo)';
  EXECUTE IMMEDIATE sqlQuery;

  doresetvalidacion(qusuario, idarchivo);

  IF (tipoDependencia = 'PEC') THEN
    dovalidapec(qusuario,qaniofiscal,idarchivo,imprimirMensajes);
    COMMIT;
  ELSIF (tipoDependencia = 'SAGARPA') THEN
    dovalidacionpec(qusuario,qaniofiscal,idarchivo,imprimirMensajes);
    COMMIT;
  END IF;

例外が発生しない場合、プロシージャは単にインデックスを削除しますが、インデックスは再作成されません! コードのこの部分だと思いました

EXCEPTION
    WHEN index_not_exists THEN NULL;

エラーを処理してから、その下のコードに進みます。EXCEPTIONこれで、例外が発生した場合にのみ実行された後の結果が表示されました。

私が望むのは、コードを単純化するEXCEPTIONことです。期待どおりに機能させるためだけに、句の前に同じコードブロックをコピーして貼り付けたくありません。それを達成する方法はありますか?多分ネストされたBEGIN ... ENDブロックで?または、コードを再利用するために別の手順を作成する必要がありますか?

乾杯。

アップデート

create or replace
PROCEDURE DOVALIDAINFORMACION 
(
  QARCHIVO IN VARCHAR2
, QUSUARIO IN VARCHAR2
, QANIOFISCAL IN VARCHAR2
) AS
  imprimirMensajes CHAR;
  tipoDependencia VARCHAR2(25);
  idArchivo NUMBER;
  sqlQuery VARCHAR2(100);
  index_not_exists EXCEPTION;
  PRAGMA EXCEPTION_INIT(index_not_exists, -1418);
BEGIN

  sqlQuery := 'DROP INDEX idArchivoIndex';
  EXECUTE IMMEDIATE sqlQuery;
  ----------------------
  EXCEPTION --En caso de que no exista el índice capturamos la excepcion
    WHEN index_not_exists THEN --y la ignoramos
      NULL;
  END;
  ----------------------
  sqlQuery := 'CREATE INDEX idArchivoIndex'||
              ' ON '||qusuario||' (id_archivo)';
  EXECUTE IMMEDIATE sqlQuery;

  doresetvalidacion(qusuario, idarchivo);

  IF (tipoDependencia = 'PEC') THEN
    dovalidapec(qusuario,qaniofiscal,idarchivo,imprimirMensajes);
    COMMIT;
  ELSIF (tipoDependencia = 'SAGARPA') THEN
    dovalidacionpec(qusuario,qaniofiscal,idarchivo,imprimirMensajes);
    COMMIT;
  END IF;

END DOVALIDAINFORMACION;

しかし、プロシージャをコンパイルできません。

Error(32,3): PLS-00103: Se ha encontrado el símbolo "SQLQUERY"
Error(33,48): PLS-00103: Se ha encontrado el símbolo ";" cuando se esperaba uno de los siguientes:     ) , * & = - + < / > at in is mod remainder not rem    <an exponent (**)> <> or != or ~= >= <= <> and or like LIKE2_    LIKE4_ LIKEC_ between || member SUBMULTISET_ 
4

1 に答える 1

2

BEGIN更新されたコードに余分なものが欠けているのではないかと思います。EXCEPTION句は常にaBEGINと。に一致しENDます。投稿したコードではEXCEPTION、プロシージャのに一致しますBEGINBEGINネストされたPL/SQLブロックのと一致する必要があります。

create or replace
PROCEDURE DOVALIDAINFORMACION 
(
  QARCHIVO IN VARCHAR2
, QUSUARIO IN VARCHAR2
, QANIOFISCAL IN VARCHAR2
) AS
  imprimirMensajes CHAR;
  tipoDependencia VARCHAR2(25);
  idArchivo NUMBER;
  sqlQuery VARCHAR2(100);
  index_not_exists EXCEPTION;
  PRAGMA EXCEPTION_INIT(index_not_exists, -1418);
BEGIN
  BEGIN
    sqlQuery := 'DROP INDEX idArchivoIndex';
    EXECUTE IMMEDIATE sqlQuery;
  EXCEPTION --En caso de que no exista el índice capturamos la excepcion
    WHEN index_not_exists THEN --y la ignoramos
      NULL;
  END;

  sqlQuery := 'CREATE INDEX idArchivoIndex'||
              ' ON '||qusuario||' (id_archivo)';
  EXECUTE IMMEDIATE sqlQuery;

  doresetvalidacion(qusuario, idarchivo);

  IF (tipoDependencia = 'PEC') THEN
    dovalidapec(qusuario,qaniofiscal,idarchivo,imprimirMensajes);
    COMMIT;
  ELSIF (tipoDependencia = 'SAGARPA') THEN
    dovalidacionpec(qusuario,qaniofiscal,idarchivo,imprimirMensajes);
    COMMIT;
  END IF;
END DOVALIDAINFORMACION;

余談ですが、PL/SQLブロックにインデックスを削除してすぐに再作成するのは奇妙に思えます。これが、ロード後にインデックスを再作成することについてのあなたの質問に何らかの形で関連している場合は、私の答えを誤解している可能性があります。以前の回答では、インデックスを削除し、1,000万行のデータを読み込んでから、インデックスを再作成する方が効率的である可能性があることを指摘していました。このコードで行っているストアドプロシージャの呼び出しでロードが発生していると仮定すると、ロードの完了にインデックスを再作成する必要があります。

于 2012-04-19T21:12:29.360 に答える