2017-10-31 28 views
1

私は奇妙な問題を抱えています。CURSOR FORループはストアドプロシージャ内にあります。わかりやすくするために、私はDBeaver内でOracleを使用しており、テーブル内のすべての列をループしてselect文の結果を出力しようとしています。ストアドプロシージャのカーソルForループ内でdbms_output.put_lineが機能しない

Iは、正確なコードへのアクセス権を持っていないが、これは機能的に近似である:

CREATE OR REPLACE PROCEDURE column_null(table_name_in IN VARCHAR2) 
AS 
str_query VARCHAR2(1000); 
temp_number NUMBER(10); 
CURSOR col_cursor IS 
SELECT * FROM user_tab_cols 
WHERE table_name = table_name_in; 

BEGIN 
FOR c_id IN col_cursor 
LOOP 
    str_query := 'select COUNT(*) FROM ' || table_name_in || 
       ' WHERE ' || c_id.column_name || ' IS NOT NULL'; 
    EXECUTE IMMEDIATE str_query INTO temp_number; 
    DBMS_OUTPUT.PUT_LINE(temp_number); 
END LOOP; 
END; 

今、奇妙な部分であることを私は(マイナス格納された関数の外このまったく同じコードブロックを実行した場合余分なDECLAREキーワード)、期待どおりに動作します。たとえループ内で 'Hello'をエコーし​​ようとしても、期待通りに動作しますが、を停止するストアドプロシージャになるとすぐにとなります。私は今日これを何時間もテストしてきましたが、完全に困惑しています。参考までに、私は最近PL/SQLに精通していますので、その謎が私を逃れます。

さらに、それはに特有のようです。CURSOR FORループ。 Cursor Forループを一般的な数値ループ(すなわち、FOR c_id IN 1 .. 10)に置き換えると、プロシージャによって出力が正しく出力されます。影響を受けるのはDBMS_OUTPUT.PUT_LINEだけではありません。かなり多くすべてのは、通常のPL/SQLブロックではうまく動作していても、変数の更新を含むストアドプロシージャでは無視されます。

要約::PL/SQLブロックとして正常に動作し、数値forループで正常に動作しますが、ストアドプロシージャとカーソルforループの正確な組み合わせによって出力が生成されません。実際に私のテストでは、ストアド・ファンクションのカーソル・ループ内で何の意味もないように思えます。

これはDBeaverのバグですか? PL/SQLの奇妙さ?プロシージャやカーソルForループの働きにより期待される振る舞いであるかどうか、あるいはこれが何らかのバグであるかどうかはわからないので、私はここに投稿しています。

+0

動的SQLのデータは印刷できません。 REF-CURSORでハンドルすれば、解決策を得ることができます。 –

+0

SQLデベロッパーの 'SET SERVEROUTPUT ON'を使ってうまく動作します。 –

+0

実際にプロシージャを実行していますか? PLSQLブロックを作成して実行すると、結果が直接表示されます。しかし、プロシージャの場合は、プロシージャをコンパイルしてから実行する必要があります。'exec_null( 'Yourtablename');' – XING

答えて

0

プロシージャを宣言することです。宣言したので、あなたは以下のようなプログラムを使って呼び出す必要があります。ほとんどの場合、出力を生成します。

オプション01

set serveroutput on; 
    Declare 
     v_table_name_in IN VARCHAR2(499); 

    Begin 
     v_table_name_in := 'your table name'; 
     column_null(table_name_in => v_table_name_in); 
    end; 

オプション02 は戻りパラメータを取得します。理想的にはout型のパラメータとしてテーブル型。上記のコードの中でループして値を出力します。

オプション03. 出力をログテーブルに記録します。

+0

記録のために、私は他のプロシージャのために見つける 'BEGIN column_null( 'table_name')END;'を使ってプロシージャを呼び出しています。私はより多くを学ぶときにオプション2を調べます。 –

0

このエラーは、手順にAUTHID current_userを単に追加することで解決されました。明らかに、プロシージャには選択しようとしているテーブルにアクセスする権限がありませんでした。しかし、奇妙なことに、プロシージャを実行しようとするとエラーは発生しませんでした。それは単に出力を生成しませんでした。

関連する問題