2

厳密に最適化問題があります。プロシージャ/関数が何度も呼び出される場合、パッケージのどこにCONSTANT変数を配置する必要がありますか?

これを見てみましょう:

CREATE OR REPLACE PACKAGE WB_TEST IS
  PROCEDURE TEST;
END WB_TEST;

CREATE OR REPLACE PACKAGE BODY WB_TEST IS
  FUNCTION PARSER(IN_PARAM IN VARCHAR2) RETURN VARCHAR2 IS
    LC_MSG   CONSTANT VARCHAR2(80) := 'Hello USERNAME! How are you today?';
    LC_PARAM CONSTANT VARCHAR2(10) := 'USERNAME';
  BEGIN
    RETURN REPLACE(LC_MSG, LC_PARAM, IN_PARAM);
  END PARSER;

  PROCEDURE TEST IS
  BEGIN
    FOR I IN 1 .. 1000 LOOP
      DBMS_OUTPUT.PUT_LINE(PARSER(TO_CHAR(I)));
    END LOOP;
  END TEST;
BEGIN
  DBMS_OUTPUT.ENABLE(1000000);
END WB_TEST;
/

または、そのようなことをする方が良いです:

CREATE OR REPLACE PACKAGE WB_TEST IS
  PROCEDURE TEST;
END WB_TEST;

CREATE OR REPLACE PACKAGE BODY WB_TEST IS
  GC_MSG   CONSTANT VARCHAR2(80) := 'Hello USERNAME! How are you today?';
  GC_PARAM CONSTANT VARCHAR2(10) := 'USERNAME';

  FUNCTION PARSER(IN_PARAM IN VARCHAR2) RETURN VARCHAR2 IS
  BEGIN
    RETURN REPLACE(GC_MSG, GC_PARAM, IN_PARAM);
  END PARSER;

  PROCEDURE TEST IS
  BEGIN
    FOR I IN 1 .. 1000 LOOP
      DBMS_OUTPUT.PUT_LINE(PARSER(TO_CHAR(I)));
    END LOOP;
  END TEST;
BEGIN
  DBMS_OUTPUT.ENABLE(1000000);
END WB_TEST;
4

1 に答える 1

3

パフォーマンスの観点からは、問題になる可能性はほとんどありません。PL / SQLコンパイラが生成するコードは、どちらの場合も同一である必要があります。定数は、参照される場所でほぼ確実にインラインでコンパイルされます。

どちらか一方を優先する唯一の理由は、コードの明確さと変数のスコープです。定数が実際にPARSER関数に対してローカルである場合、つまり、パッケージ内の他のメソッドに役立つ可能性が低い場合は、関数の一部として宣言する必要があります。一方、パッケージ内の他のメソッドに役立つ可能性が高い場合は、パッケージ本体の一部として宣言する必要があります。それらがパッケージ外のメソッドに役立つ可能性が高い場合は、パッケージ仕様の一部として宣言する必要があります。

于 2012-09-20T17:29:21.583 に答える