PL/SQL 実行中のSIDを取得する方法

このQ&Aのポイント
  • 自作のストアドプロシージャで実行中の関数のSIDを取得する方法を知りたいです。
  • DBMS_**** パッケージの使用例を紹介するので、関数の実行時にSIDと関数名を取得できる方法を教えてください。
  • PL/SQLで特定の関数の実行時に実行中のセッションのSIDと関数名を記録する方法について教えてください。
回答を見る
  • ベストアンサー

PL/SQL 実行中のSID

自作のストアドプロシージャのどの関数がいつ呼ばれたかを記録したいと思いました。 例えば FUNC_A という関数があって、その関数の先頭で、その関数を実行しているセッションのSIDと関数名を取得できないものでしょうか。 そのようなパッケージ DBMS_**** みたいなものがあって、下記のような感じで使えたらなあと考えています。 ------------------ FUNC_A IS sid NUMBER; funcName VARCHAR2(30); BEGIN SELECT DBMS_****.GET_EXECUTING_SID INTO sid FROM DUAL; SELECT DBMS_****.GET_CURRENT_FUNC INTO funcName FROM DUAL; ... (sid と funcName を現時刻とともに記録) END; ------------------ このような目的に合致したパッケージ、あるいはこの目的を実現する方法などありますでしょうか。 よろしくお願いします

  • Oracle
  • 回答数3
  • ありがとう数6

質問者が選んだベストアンサー

  • ベストアンサー
  • yamada_g
  • ベストアンサー率68% (258/374)
回答No.3

dda167さん 蛇足や余計なお世話などではありませんね。 質問者さんの欲しい値を取るには、 select SYS_CONTEXT ('USERENV', 'SID') from dual; こちらですね・・・ ご指摘ありがとうございました。 また、関数名について回答していませんでした。 確実に使えるかは分からないですが、DBMS_UTILITY.FORMAT_CALL_STACKの戻り値のコールスタックの内容から取得できるかもしれません。 当方の環境(10g XE)で少し試してみました。 インデントしていないので見づらいですが・・ --ストアド名を返すファンクション create or replace function get_name return varchar2 is callstack varchar2(2000); currentname varchar2(2000); begin callstack := DBMS_UTILITY.FORMAT_CALL_STACK; /* コールスタックの最初には、このファンクション自身の情報が入っているため 2つ目のストアド名を取得する */ currentname := regexp_substr(callstack, 'procedure.+$|function.+$|package.+$',1,2,'im'); return currentname; end; / --上記ファンクションを呼ぶだけのファンクション create or replace function func_a return number is begin dbms_output.put_line(get_name); return 0; end; / --プロシージャ create or replace procedure proc_a is begin dbms_output.put_line(get_name); end; / --パッケージ create or replace package pack_a is procedure proc_a; end; / create or replace package body pack_a is procedure proc_a is begin dbms_output.put_line(get_name); end; end; / --無名ブロックで上記ファンクションらを実行 set serveroutput on declare w_num number; begin w_num := func_a; --function スキーマ名.FUNC_A proc_a; --procedure スキーマ名.PROC_A pack_a.proc_a; --package body スキーマ名.PACK_A end; / set serveoutput off 無名ブロックのコード内にある、コメントの内容が出力されました。 パッケージの場合は、プロシージャ名までは取得できないようです。 参考になれば幸いです。

shingo-numtech
質問者

お礼

詳しい情報をありがとうございました これからいろいろと試してみたいと思います

その他の回答 (2)

  • dda167
  • ベストアンサー率76% (55/72)
回答No.2

蛇足(余計なお世話)ですが SYS_CONTEXTで取得するSESSIONIDは、V$SESSIONのAUDSIDです。 念のためです。失礼しました。

  • yamada_g
  • ベストアンサー率68% (258/374)
回答No.1

select SYS_CONTEXT ('USERENV', 'SESSIONID') from dual; でセッションIDが取得できます。 http://docs.oracle.com/cd/E16338_01/server.112/b56299/functions184.htm

関連するQ&A

  • PL SQL のループ

    あるセレクト文のパフォーマンスを測定するためにループで複数回実行し時間を測定したいのですが、select 変数 into をしないとコンパイルできず実行できません。 同じセレクト文を複数回実行し時間を測定するのに良い方法は無いでしょうか? CREATE OR REPLACE PROCEDURE test IS BEGIN DBMS_OUTPUT.PUT_LINE(TO_CHAR(sysdate(),'YYYY/MM/DD HH24:MI:SS')); FOR i IN 1..100 LOOP SELECT a,b,c,d,e FROM tbl; END LOOP; DBMS_OUTPUT.PUT_LINE(TO_CHAR(sysdate(),'YYYY/MM/DD HH24:MI:SS')); END;

  • PL/SQLでのSQL文法

    こんにちは。教えてください。 PL/SQLを使うのが初めで戸惑っています。 まず、PROCEDUREで =========================== BEGIN SELECT NAME FROM TABLE1 WHERE NAME='tanaka'; END; / =========================== このように書いて実行させようとすると、「コンパイルエラー」 「INTO句はこのSELECT文に入ります」というエラーが出ます。 SQLの文法的には間違ってないと思うのですが、INTO句とはこれいかに?? ネットでPL/SQLで検索かけて調べたのですがあまりにも初歩すぎて わかりませんでした。 PL/SQLやORACLEのメーリングリストでお勧めがありましたら教えてください。 よろしくお願いいたします。

  • PL/SQLでエラー

    PL/SQLの使用方法を検討しており、下記のようにサンプルを作成しました。 //1. 宣言部 create or replace package Pac is procedure Pro1(p1 in varchar2); end; / パッケージが作成されました //2. 本体 create or replace package body Pac is procedure Pro1(p1 in varchar2) is tempdate DATE; begin select to_char(sysdate, 'yyyy/mm/dd') INTO tempdate from dual; DBMS_OUTPUT.PUT_LINE('引数は' || p1 || 'です。'); DBMS_OUTPUT.PUT_LINE('日付は' || tempdate || 'です。'); end; end; / パッケージ本体が作成されました //3. 実行 execute Pac.Pro1('a'); // エラー内容 行1でエラーが発生しました。: ORA-00900: invalid SQL statement SQLPlusより、上記の[1. 宣言部]でパッケージを作成し、[2. 本体]で本体部分を作成しました。 その後、[3. 実行]を実施しましたが、 エラーが出力されて実行されません。 何がいけないのかお気づきの点がございましたら、 よろしくお願いします。

  • 動的なSQLからカーソルを返す。

    下記のようなカーソルを返すパッケージがあったとします。 CREATE OR REPLACE PACKAGE TEST AS CURSOR C1 IS SELECT * FROM テーブル; TYPE TC1 IS REF CURSOR RETURN C1%ROWTYPE; PROCEDURE P_TEST(in条件 IN CHAR, CU OUT TC1); END; CREATE OR REPLACE PACKAGE BODY TEST IS PROCEDURE P_TEST(in条件 IN CHAR, CU OUT TC1) AS sqlStr VARCHAR2(1000); cur NUMBER; r NUMBER; BEGIN cur := DBMS_SQL.OPEN_CURSOR; sqlStr := 'OPEN CU FOR SELECT * FROM テーブル WHERE 条件 = ' || in条件; DBMS_SQL.PARSE(cur, sqlStr, DBMS_SQL.NATIVE); DBMS_SQL.DEFINE_COLUMN(cur, 1, CU); r := DBMS_SQL.EXECUTE(cur); DBMS_SQL.CLOSE_CURSOR(cur); END; SELECTした結果のカーソル(CU)をクライアントで取得したいのですけど 技術的に可能でしょうか? ストアドのコンパイル時に→DBMS_SQL.DEFINE_COLUMN(cur, 1, CU);が エラーとなります。 DBMS_SQL.DEFINE_COLUMNではカーソルタイプは取得できないとわっかたの ですがカーソルを取得する為のDBMS_SQL.DEFINE_COLUMNにかわる DBMS_SQL.?????はないでしょうか? いろいろ調べたのですが手に負えず。 どなたか教えてください。

  • GET_DDLについて

    DBMS_METADATA.GET_DDLを使い定義情報を取得しようとしています。 尚、各定義情報は名前を指定せず、全て取得したいです。 テーブル、ビュー、Indexは以下のようにして取得できました。 (select DBMS_METADATA.GET_DDL('TABLE',table_name) from user_tables;) パッケージ、パッケージボディ、ファンクション、プロシージャーの取得方法が 分かりません。 一応、以下のように名前を指定すると取得できました。 select DBMS_METADATA.GET_DDL('PROCEDURE','名前') from dual; 名前を指定せず、全て取得する方法が分かりません。 パッケージ、パッケージボディ、ファンクション、プロシージャーに関して 全て取得する方法をご教授おねがいします。

  • PL/SQLでSPOOLさせたいのですが、可能でしょうか?

    PL/SQLにてSPOOLにてSELECTの結果を ファイル出力させたいのですが、 (下記のような感じです。) エラーとなってしまいます。 そもそも、PL/SQLにてSPOOLは使用可能なのでしょうか? 例) declare  begin   spool c:\test_spool.dat    select * from dual;   spool off end; この例では 「PLS-00103: 記号"C"が見つかりました。」という エラーメッセージがかえってきます。。。 出力ファイルの指定のしかたが悪いのでしょうか? ご教授いただければ幸いです。 DBはOracle9iです。

  • PL/SQL ORA-06502エラーに関して(動的SQL)

    こんにちは、いつもお世話になっております。 現在、会社で動的SQLを使用してとある開発をおこなっているのですが、 どうしても上手くいかないので、どなたか教えて下さいm(__)m 下記の動的SQL文で最後から2行目のSQL:DBMS_OUTPUT.PUT_LINE(varDel); を実行するとORA-06502: PL/SQL: 数値または値のエラー: 文字列バッファが小さすぎます。のエラーが 発生します、過去ログやgoogleで検索をかけてみたのですが、 どうにも解決方法がわからず困っています・・・・ お知恵のある方、教えて下さいませm(__)m ※多分、sql文が長いせいだとは思うのですが、どうしても これ以上は短くできず、静的ではなく、動的で動かさなければならない という条件付きなんですが、宜しく御願いします。 DECLARE numkeepD NUMBER := 0; -- データ保管期間格納用 varAST VARCHAR2(4) := '**'; -- アクセス区分定義外格納用 varkeepD VARCHAR2(2000); -- KEEP_DAYS取得SQL文格納用 varDel VARCHAR2(2000); -- DELETE文格納用 BEGIN varkeepD := 'SELECT KEEP_DAYS FROM SMCI4T910 WHERE ACC_KBN = '''||varAST||''''; DBMS_OUTPUT.PUT_LINE(varkeepD); EXECUTE IMMEDIATE (varkeepD) INTO numkeepD; DBMS_OUTPUT.PUT_LINE(numkeepD); -- アクセスログデータ削除SQL文格納 varDel := 'DELETE FROM '||cTABLE_STCI1T910||' ST910 ' ||'WHERE ' ||'ST910.DELETE_FLG = SCIS_CTS.cDEL_NO AND ' ||'EXISTS(' ||'SELECT 1 ' ||'FROM SMCI4T910 SM910 ' ||'WHERE ' ||'ST910.ACC_KBN = SM910.ACC_KBN AND ' ||'ST910.ACC_CYMD < TO_CHAR(SYSDATE - SM910.KEEP_DAYS,''YYYYMMDD'') AND ' ||'ST910.ACC_KBN <> varAST AND ' ||'SM910.DELETE_FLG = SCIS_CTS.cDEL_NO)'; DBMS_OUTPUT.PUT_LINE(varDel); --EXECUTE IMMEDIATE (varDel) END;

  • PL/SQLのエラー処理について

    PL/SQLを勉強し始めたのですが、テーブルを作成してから、データを流し込むという処理をしたいのですが、テーブルの作成に失敗しらたら、処理を終了させるという処理はできないのでしょうか? それとも、考え方が違うのでしょうか?アドバイスお願いします。 次のようにPL/SQLを作成しています。 例) declare curHandle1 INTEGER; begin curHandle1 := DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(curHandle1, 'create table xxx as select * from xxx where ID=-1', DBMS_SQL.V7); DBMS_SQL.CLOSE_CURSOR(curHandle1); exception when OTHERS then エラーになったら、処理終了したい(次のブロックにいきたくない) end; declare begin      insert into xxx NOLOGGING values (1,'test'); end; よろしくお願いします。

  • テーブル名が可変の動的SQLをファンクションにしたい

    Oracle9iのWindowsXP環境です。 以下のようなPL/SQLを作成しましたが、同じようなselect文の繰り返しなので整理したいのと、レスポンスが悪いのでファンクションにしたいのですが、テーブル名が可変のため上手くいきません。「Table&1」は置換変数で、batファイルからパラメータが渡り、「Table200812」のように変更されます。 【***.bat】 set /p phara sqlplus -s ***/***@*** ***.sql %phara% 【***.sql】 省略 begin select aaa into a1 from Table&1 where code = 'AAAAA'; ・・ select aaa into a2 from Table&1 where code = 'BBBBB'; ・・ select aaa into a3 from Table&1 where code = 'CCCCC'; ・・ 省略 end; / 以下、試しに作成しようとしたファンクションですが、やはり予想どおりですが「表がありません」とコンパイルエラーになります。 create function Func_test(code IN varchar2, Table1 IN varchar2) return number is ret number; begin select aaa into ret from Table1 where code = 'code'; return ret; end; / ※コール側は、「a1 = Func_Test('AAAAA', Table&1);」 そもそもこれが実現できたとしてレスポンスが上がるものなのでしょうか?どちらにせよコードを整理する意味でもファンクションにはしたいのですが。。 宜しくお願い致します。

  • PL/SQLの動的SQLで複数の項目を取得する方法教えて下さい。

    動的SQLで複数の項目を取得する方法で 悩んでいます。 下記の例だと、1項目しか取れません。 何か他のやり方でもいいので、複数の項目を 取得する方法を教えていただきたいです。 ********************************************* declare sql_stmt varchar2(200); wk_grp varchar2(5); wk_name varchar2(30); type cursor_type is ref cursor; cur_name cursor_type; begin wk_grp := '1u'; open cur_name for 'select 名前 from 社員表 where 所属グループ = :v1' using wk_grp; loop fetch cur_name into wk_name; exit when cur_name%notfound; dbms_output.put_line(wk_name); end loop; close cur_name; end; ********************************************* 下記のようなDBMS_SQLパッケージ?? を利用した方法がいいんでしょうかね。。。。 DBMS_SQL.COLUMN_VALUE(SQL,1,WK_NAME) DBMS_SQL.COLUMN_VALUE(SQL,2,WK_NO) よくわかってないので、宜しくお願いします。