0

編集:完全なコードについては、以下の編集を参照してください。最初のものは機能します。これは、タイトルにあるものとは別の問題かもしれません。

カーソルのカウント結果を整数にしようとしていますが、整数は常に 0 のままです。

DECLARE    
   v_count int := 0;

CURSOR logins IS
   SELECT count(*)
   FROM big_table;

BEGIN
OPEN logins;
FETCH logins into v_count;

IF v_count > 10 THEN
   DBMS_OUTPUT.PUT_LINE ('Hi mom');
END IF;

CLOSE logins;
END;

これは、これを実行したいコードのサンプルにすぎません。このフェッチは実際にはループ内にあります。

IF文の前に「SELECT count(*) INTO v_count...」を入れてみました。動作しますが、非常に遅いです。

ありがとうございました!

編集: ABCAD で指摘されているように、このサンプルは機能します。したがって、私の問題はコードの他の場所にある可能性があります。以下にすべてを示します。

DECLARE
    v_hour int := 0;
    v_maxConn int;
    v_count int;
    --set the time parameters
    --v_day = the first day you loop in
    v_day int := 16;
    v_month varchar2 (2) := 10;
    v_year varchar2 (4) := 2013;
    v_lastDay int := 16;

CURSOR logins IS

        SELECT count(*)
        FROM (
            SELECT (SELECT user_function_name
            FROM apps.fnd_form_functions_vl fffv
            WHERE (fffv.function_id = a.function_id)) "Current Function",
               first_connect,
               last_connect,
               user_name, session_id,
               apps.fnd_profile.value_specific
                                    ('ICX_SESSION_TIMEOUT',
                                     a.user_id,
                                     a.responsibility_id,
                                     a.responsibility_application_id,
                                     a.org_id,
                                     NULL
                                    ) TIMEOUT,
               counter "How many hits a User has made",
               a.limit_connects "No of hits allowed in session"
            FROM icx.icx_sessions a, fnd_user b
            WHERE a.user_id = b.user_id
            AND last_connect > SYSDATE - 30
            AND b.user_name NOT LIKE 'GUEST'
             )
        WHERE to_date(v_year || '-' || v_month || '-' || v_day || ' ' || v_hour || ':00:00','YYYY-MM-DD HH24:MI:SS') between first_connect and last_connect
        ;

    out_menu varchar2(500);
    out_path varchar2(50) := '/usr/tmp/QA';
    file_out utl_file.file_type ;

BEGIN
file_out := utl_file.fopen(out_path,'debug_rapport.txt','W');
OPEN logins;

LOOP EXIT WHEN v_day > v_lastDay;
    v_maxConn := 0;

    LOOP EXIT WHEN v_hour > 23;

        FETCH logins into v_count;

        IF v_count > v_maxConn THEN
           v_maxConn := v_count;
        END IF;

        out_menu := 'Debug: ' || to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') || ' -> dateLoop: ' || to_date(v_year || '-' || v_month || '-' || v_day || ' ' || v_hour || ':00:00','YYYY-MM-DD HH24:MI:SS') || ' -> v_maxConn: ' || v_maxConn || ' -> hour:' || v_hour;
        utl_file.put_line(file_out,out_menu);

        v_hour := v_hour + 1;

    END LOOP;

    DBMS_OUTPUT.PUT_LINE (v_year || '-' || v_month || '-' || v_day || ';' || v_maxConn);

    v_hour := 0;
    v_day := v_day + 1;

END LOOP;

CLOSE logins;

END;

コードは、指定された 1 日のストレッチの各時間内に同時接続を確認することです。BEGIN ステートメントのカーソル コードを、カーソル内にある SELECT ステートメントに置き換えると機能します。

カーソルを使用したときの「デバッグ」ファイルからの出力は次のとおりです。

Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:0
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:1
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:2
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:3
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:4
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:5
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:6
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:7
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:8
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:9
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:10
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:11
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:12
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:13
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:14
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:15
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:16
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:17
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:18
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:19
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:20
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:21
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:22
Debug: 2013-10-24 10:19:32 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:23

そして、カーソルを "SELECT count(*) INTO v_count [...]" に置き換えたときの出力は次のとおりです。

Debug: 2013-10-24 10:00:40 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:0
Debug: 2013-10-24 10:00:54 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:1
Debug: 2013-10-24 10:01:09 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:2
Debug: 2013-10-24 10:01:23 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:3
Debug: 2013-10-24 10:01:37 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:4
Debug: 2013-10-24 10:01:50 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:5
Debug: 2013-10-24 10:02:05 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:6
Debug: 2013-10-24 10:02:20 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:7
Debug: 2013-10-24 10:02:33 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:8
Debug: 2013-10-24 10:02:47 -> dateLoop: 13-10-16 -> v_maxConn: 0 -> hour:9
Debug: 2013-10-24 10:03:00 -> dateLoop: 13-10-16 -> v_maxConn: 1 -> hour:10
Debug: 2013-10-24 10:03:15 -> dateLoop: 13-10-16 -> v_maxConn: 1 -> hour:11
Debug: 2013-10-24 10:03:28 -> dateLoop: 13-10-16 -> v_maxConn: 1 -> hour:12
Debug: 2013-10-24 10:03:41 -> dateLoop: 13-10-16 -> v_maxConn: 1 -> hour:13
Debug: 2013-10-24 10:03:54 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:14
Debug: 2013-10-24 10:04:08 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:15
Debug: 2013-10-24 10:04:22 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:16
Debug: 2013-10-24 10:04:35 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:17
Debug: 2013-10-24 10:04:47 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:18
Debug: 2013-10-24 10:05:00 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:19
Debug: 2013-10-24 10:05:13 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:20
Debug: 2013-10-24 10:05:25 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:21
Debug: 2013-10-24 10:05:38 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:22
Debug: 2013-10-24 10:05:51 -> dateLoop: 13-10-16 -> v_maxConn: 2 -> hour:23

v_maxConn がゼロにとどまらないことがわかります。したがって、v_count が書き込まれています。ただし、1日5分しかかかりません。

あなたの助けは大歓迎です!

4

3 に答える 3

0

あなたは奇妙なことをしています-あなたはループしv_hourv_dateいますが、1つのレコードしか含まれていない同じ開かれたカーソルを再フェッチしています.

つまり、基本的に何が起こっているかというと、同じ値 (0) を何度も取得しているということです。

これは、あなたのケースによく似たサンプルを含むsqlfiddleデモです。

OPEN logins;

for v_i in 1..10 loop
FETCH logins into v_count;

IF v_count > 10 THEN
   v_res := v_res ||v_i || '. v_count=' || v_count || ', ';
END IF;

end loop;
CLOSE logins;

本当にそうしたい場合は、カーソルにパラメーターを追加し、反復ごとに再度開く必要があります。

これが機能する別のサンプルです

for v_i in 1..10 loop
OPEN logins(v_i);
FETCH logins into v_count;

IF v_count > 10 THEN
   v_res := v_res ||v_i || '. v_count=' || v_count || ', ';
END IF;
CLOSE logins;
end loop;

しかし、これは反復ごとに count(*) をクエリするようなものです (遅くなる可能性があります)。

言うのは難しいですが、1回のクエリで値を取得できるように見えます-

このようなもの

于 2013-10-24T15:27:15.460 に答える
0

私はあなたのコードを少し修正しました、これはうまくいきます..

DECLARE    
   v_count int := 0;

CURSOR logins IS
   SELECT count(*)
   FROM big_table;

BEGIN

OPEN logins;

loop

FETCH logins into v_count;



IF v_count >= 10 THEN

   DBMS_OUTPUT.PUT_LINE ('Hi mom');

   exit;

END IF;

end loop;

CLOSE logins;

END;

ループ、ループの終了、および終了するステートメントを忘れました。そうしないと、無限ループが発生します...これが役立つことを願っています。10行未満になると無限ループになります。

于 2013-10-24T14:49:46.087 に答える
0

問題は、カーソルがどのように機能するかを完全に理解していなかったことです。カーソルを、静的クエリを配置する一時テーブルに置き換えました。

CREATE TABLE apps.audit_custom as
select [...]

次に、LOOP でこのテーブルをクエリします。

SELECT count(*) into v_count
        FROM apps.audit_custom
        WHERE to_date(v_year || '-' || v_month || '-' || v_day || ' ' || v_hour || ':00:00','YYYY-MM-DD HH24:MI:SS') between first_connect and last_connect;

最後に、作業が終わったらテーブルをドロップします。

これは、自分のアイデアを実現するために見つけた最速の方法です。

みんな助けてくれてありがとう!

于 2013-10-25T19:49:36.587 に答える