1. ホーム
  2. oracle

[解決済み] ORA-04021: オブジェクトのロック待ちでタイムアウトが発生しました。

2022-02-06 23:42:15

質問

あるテーブルから返される値を計算し、表示する匿名PL/SQLブロックがあります。

DECLARE
    U_ID NUMBER :=39;
    RETAIL BINARY_FLOAT:=1;
    FLAG NUMBER;
BEGIN
    SELECT NVL(RETAIL_AMOUNT,1),UNIT_ID INTO RETAIL, FLAG FROM UNITS WHERE UNIT_ID=U_ID;
    LOOP
    SELECT NVL(MAX(UNIT_ID),U_ID) INTO FLAG FROM  UNITS WHERE FATHER_ID=FLAG;
    IF FLAG=U_ID THEN EXIT; END IF;
    SELECT RETAIL* RETAIL_AMOUNT INTO RETAIL FROM UNITS WHERE UNIT_ID=FLAG;
    EXIT WHEN FLAG=U_ID;
    END LOOP;
DBMS_OUTPUT.PUT_LINE( RETAIL);
END;

このブロックは正しく動作しますが、同じことをPL/SQL関数を使って行いたいと思いました。

以下のように関数を書きました。

CREATE OR REPLACE FUNCTION GET_UNIT_RETAIL(U_ID NUMBER)
     RETURN NUMBER
IS
    RETAIL BINARY_FLOAT:=1;
    FLAG NUMBER;
BEGIN
    SELECT NVL(RETAIL_AMOUNT,1),UNIT_ID 
    INTO RETAIL, FLAG 
    FROM UNITS 
    WHERE UNIT_ID=U_ID;

    LOOP
        SELECT NVL(MAX(UNIT_ID),U_ID) 
        INTO FLAG 
        FROM  UNITS 
        WHERE FATHER_ID=FLAG;
        IF FLAG=U_ID THEN 
            EXIT; 
        END IF;
        SELECT RETAIL* RETAIL_AMOUNT 
        INTO RETAIL 
        FROM UNITS 
        WHERE UNIT_ID=FLAG;
        EXIT WHEN FLAG=U_ID;
    END LOOP;

    RETURN NUMBER;
END;
/

上記のコードを実行して関数をデータベースに保存しようとすると、環境(SQL*PLUS)が長時間ハングアップし、最後にこのエラーを返します。

1 行目で ERROR が発生しました。
ORA-04021: オブジェクトのロック待ちでタイムアウトが発生しました。

何が問題なのでしょうか?お願いします。

解決方法は?

以下のような音がします。 ddl_lock 問題

を見てみましょう。
dba_ddl_locks をクリックすると、作成または置換をブロックしているユーザーを確認できます。

の下に作成することも試してみてください。 別の名前 - をクリックして、何が起こるか見てみましょう。