2012-01-20 21 views
5

SQL文の実行時間をテーブルに保存するプロシージャを記述する必要があります。plsqlのプロシージャ内のSQL文の測定時間

手順はexec measuresqltime('sql statement as string');

私の考えで呼んでいるが、このようなものです:

--declarations 
    timestart NUMBER; 
    BEGIN 
    dbms_output.enable; 
    timestart:=dbms_utility.get_time(); 
    EXECUTE IMMEDIATE sql 
    COMMIT; 
    dbms_output.put_line(dbms_utility.get_time()-timestart); 
    -- save time 

は、しかし、それは SELECT *...句のために私のために動作しませんでした。 (私はSQLにINTO-orderが必要だと思います)

プロシージャ内でSQL-atatementsを実行する方法はありますか?

答えて

13

SQLステートメントがSELECTの場合は、カーソルからフェッチして実行時間の有意義な尺度を取得する必要があります。

カーソルからフェッチしないと、 "解析"と "実行"フェーズで費やされた時間だけが測定されますが、多くの作業は通常SELECTステートメントのフェッチフェーズで行われます。

実際のステートメントの数がわからない場合は、EXECUTE IMMEDIATEまたはOPEN cursor FOR 'string'をフェッチできません。 SELECTの列の数/タイプが不明な場合は、動的SQLパッケージDBMS_SQLを使用する必要があります。

SQL> CREATE OR REPLACE PROCEDURE demo(p_sql IN VARCHAR2) AS 
    2  l_cursor INTEGER; 
    3  l_dummy NUMBER; 
    4  timestart NUMBER; 
    5 BEGIN 
    6  dbms_output.enable; 
    7  timestart := dbms_utility.get_time(); 
    8  l_cursor := dbms_sql.open_cursor; 
    9  dbms_sql.parse(l_cursor, p_sql, dbms_sql.native); 
10  l_dummy := dbms_sql.execute(l_cursor); 
11  LOOP 
12  EXIT WHEN dbms_sql.fetch_rows(l_cursor) <= 0; 
13  END LOOP; 
14  dbms_sql.close_cursor(l_cursor); 
15  dbms_output.put_line(dbms_utility.get_time() - timestart); 
16 END; 
17/

Procedure created. 

SQL> exec demo('SELECT * FROM dual CONNECT BY LEVEL <= 1e6'); 
744 

PL/SQL procedure successfully completed. 

注これはSELECTの最後の行にフェッチするのに必要な時間を測定すること:ここでは

は一例です。

+0

こんにちは、それはすばらしいようです:)しかし、それはfpr select文だけが動作しますか?削除または挿入文を実行するオプションはありますか? – sheepy

+0

@sheepy:DMLカーソル(INSERT/UPDATE ...)をフェッチすることはできません。この場合、12行目でエラーが発生します。例外をキャッチすると、DMLクエリとSELECTクエリの両方でこのプロシージャが機能します。 –

1

実行時間のための時間を計算するにはdevosJavaを完了

PROCEDURE MY_PROCEDURE IS 
    timeStart TIMESTAMP; 
    timeEnd TIMESTAMP; 
BEGIN 
    timeStart := SYSTIMESTAMP; 

    -- YOUR CODE HERE 

    timeEnd := SYSTIMESTAMP; 

    INSERT INTO PROC_RUNTIMES (PROC_NAME, START_TIME, END_TIME) 
    VALUES ('MY_PROCEDURE ', timeStart , timeEnd ); 
END MY_PROC; 
3

は答え...夜明けでそれを使用しないよう、P

PROCEDURE MY_PROCEDURE IS 
    timeStart TIMESTAMP; 
    timeEnd TIMESTAMP; 
    timeSecond NUMBER 
BEGIN 
    timeStart := SYSTIMESTAMP; 

    -- YOUR CODE HERE 

    timeEnd := SYSTIMESTAMP; 
    timeSecond :=((extract(hour from timeEnd)*3600)+(extract(minute from timeEnd)*60)+extract(second from timeEnd))-((extract(hour from timeStart)*3600)+(extract(minute from timeStart)*60)+extract(second from timeStart)); 
    dbms_output.put_line('finished: '||timeSecond||' seconds'); 
END MY_PROC; 
+2

'timeSecond:= extract(timeEndからの秒 - timeStart);' – Roland

0

INSERT INTO PROC_RUNTIMES(proc_nameに、START_TIME、END_TIME) VALUES( 'PROC_NAME'、TO_CHAR (SYSDATE、 'DD/MM/YYYY HH24:MI:SS')、NULL)。

ここにあなたのお問い合わせ;

INSERT INTO PROC_RUNTIMES(proc_nameに、START_TIME、END_TIME) VALUES( 'たproc_name'、NULL、TO_CHAR (SYSDATE、 'DD/MM/YYYY HH24:MI:SS'));

関連する問題