sql >> データベース >  >> RDS >> Oracle

OracleでCURSORをループするときに、EXIT WHEN命令を使用するのは悪い習慣ですか?

    はい、多くの人が悪い習慣に従っています。

    悪いスタイル

    OPEN / FETCH/CLOSEが完全に不要なコードを追加するという@Osyに同意します。さらに進んで、CURSORを使用することはほとんどないはずだと言います 。

    まず第一に、あなたは通常、プレーンSQLで可能な限り多くのことをしたいと思っています。 PL / SQLを使用する必要がある場合は、暗黙カーソルを使用してください。これにより、コード行が節約され、関連するロジックをより緊密に保つことができます。

    私は、コードの個々の単位をできるだけ小さく保つことを強く信じています。一見、CURSORのように見えます あなたがこれをするのを助けることができます。 SQLを1か所で定義し、後でPL/SQLループを実行できます。

    しかし実際には、その余分な間接層はほとんど価値がありません。多くのロジックがSQLにある場合もあれば、多くのロジックがPL/SQLにある場合もあります。しかし実際には、両方に多くの複雑なロジックを配置することはほとんど意味がありません。通常、コードは次のいずれかのようになります。

    for records in (<simple SQL>) loop
        <complex PL/SQL>
    end loop;
    

    または:

    for records in
    (
        <complex SQL>
    ) loop
        <simple PL/SQL>;
    end loop;
    

    いずれにせよ、コードセクションの1つは非常に小さくなります。コードのこれらの2つのセクションを分離することの複雑さは、コードのより大きな単一のセクションの複雑さよりも大きくなります。 (しかし、それは明らかに私の意見です。)

    パフォーマンスが悪い

    OPEN / FETCH / CLOSEを使用すると、パフォーマンスに大きな影響があります。その方法ははるかに遅い カーソルforループまたは暗黙カーソルを使用するよりも。

    コンパイラーは、一部のforループで一括収集を自動的に使用できます。ただし、Oracleのプレゼンテーションから引用すると、" PL / SQLパフォーマンス—神話を暴く " 、122ページ:

    簡単な例を次に示します。

    --Sample data
    create table t(a number, b number);
    insert into t select level, level from dual connect by level <= 100000;
    commit;
    
    --OPEN/FETCH/CLOSE
    --1.5 seconds
    declare
        cursor test_cur is
        select a, b from t;
        test_rec test_cur%rowtype;
        counter number;
    begin
        open test_cur;
        loop
            fetch test_cur into test_rec;
            exit when test_cur%notfound;
            counter := counter + 1;
        end loop;
        close test_cur;
    end;
    /
    
    --Implicit cursor
    --0.2 seconds
    declare
        counter number;
    begin
        for test_rec in (select a, b from t) loop
            counter := counter + 1;
        end loop;
    end;
    /
    


    1. sequlizejsの自己参照外部キー

    2. 外部キーを追加した後、行を削除できません

    3. MySQLシステムデータベーステーブルをInnoDBに変換できますか?

    4. データベース内のすべてのユーザーのすべてのアクセス許可/アクセスを検索するSQLServerクエリ