CftClub.ru
Клуб специалистов ЦФТ-Банк

Как вычитать пайп другой сессии ?

 
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Разработка в PL/PLUS. Оптимизация запросов Oracle
Предыдущая тема :: Следующая тема  
Автор Сообщение
Alkov
Профи


Вступление в Клуб: 23.09.2010
СообщениеПн Авг 18, 2014 09:48   Как вычитать пайп другой сессии ? Ответить с цитатой
Полезность: Нет оценки
Здравствуйте!

Собственно известен SID сессии как вычитать пайп к этой
сессии, сначала найти потом вычитать...
Вычитать наверное через dbms_pipe.receive_message( ) ?
Damir
Участник - экстремал


Вступление в Клуб: 29.03.2013
СообщениеВт Авг 19, 2014 08:37   Re: Как вычитать пайп другой сессии ? Ответить с цитатой
Полезность: Нет оценки
Alkov пишет:
Здравствуйте!
Собственно известен SID сессии как вычитать пайп к этой
сессии, сначала найти потом вычитать...

если речь об отладочной райпе - то она так и называется:
replace( 'debug$<<session_id>>', '<<session_id>>', session_id)



Alkov пишет:
Вычитать наверное через dbms_pipe.receive_message( ) ?

Если речь про ЦФТ, то есть пакет stdio - там и смотри функции работы с пайпой.
Alkov
Профи


Вступление в Клуб: 23.09.2010
СообщениеВт Авг 19, 2014 09:54   Re: Как вычитать пайп другой сессии ? Ответить с цитатой
Полезность: Нет оценки
Damir пишет:
Alkov пишет:
Здравствуйте!
Собственно известен SID сессии как вычитать пайп к этой
сессии, сначала найти потом вычитать...

если речь об отладочной райпе - то она так и называется:
replace( 'debug$<<session_id>>', '<<session_id>>', session_id)

Хм. у меня совпадает не session_id. а с CLIENT_INFO
пока пробую так

v varchar2(32767);
for (SELECT s(S.[CLIENT_INFO] :cl)
in V$SESSION%rowtype
where S.[SID] in нужные сессии
)
loop
v:=stdio.get_pipe_text('DEBUG$'||s.[CL],1);
end loop;
Damir
Участник - экстремал


Вступление в Клуб: 29.03.2013
СообщениеВт Авг 19, 2014 12:03   Re: Как вычитать пайп другой сессии ? Ответить с цитатой
Полезность: 1
Alkov пишет:

Хм. у меня совпадает не session_id. а с CLIENT_INFO

В CLIENT_INFO цфт прописывает комбинцию из полей системной вьюшки gv$session - INST_ID, SID, SERIAL#
т.е. то, что возвращает
Код:
dbms_session.unique_session_id()
Damir
Участник - экстремал


Вступление в Клуб: 29.03.2013
СообщениеВт Авг 19, 2014 12:16   Re: Как вычитать пайп другой сессии ? Ответить с цитатой
Полезность: Нет оценки
Alkov пишет:
v:=stdio.get_pipe_text('DEBUG$'||s.[CL],1);

В мониторе ORAMON можно имя пайпы указать - тогда и код писать не надо.
Пайпу вычитать можно только 1 раз. Т.е. если ты её вычитал, то пользователь НЕ получит сообщения в мониторе (вдруг, сидит и ждет)
Random
Эксперт


Вступление в Клуб: 27.06.2011
СообщениеСр Авг 20, 2014 09:09   Re: Как вычитать пайп другой сессии ? Ответить с цитатой
Полезность: Нет оценки
Alkov пишет:
Здравствуйте!

Собственно известен SID сессии как вычитать пайп к этой
сессии, сначала найти потом вычитать...
Вычитать наверное через dbms_pipe.receive_message( ) ?


Код:

declare
pragma macro(except, '[1]   exception;
[1]_EXCEPTION    constant number :=   [2];
pragma exception_init([1],   [2])', substitute);

pragma macro(raise_, 'message.raise_([1]_EXCEPTION,[2])', substitute);

&except(UNKNOWN_MODE,         -20123);
&except(TIMED_OUT,            -20124);
&except(TOO_LARGE_VALUE,      -01401);


function read_pipe(p_name varchar2, p_timeout integer := 2) return varchar2 is
v   varchar2(32767);
n   number;
begin
   n := dbms_pipe.receive_message(p_name,p_timeout);

   if n = 0 then
      dbms_pipe.unpack_message(v);
      return v;

   elsif n = 1 then
      &raise_(TIMED_OUT, 'Время ожидания вышло');

   elsif n = 3 then
      return null;   --   Прервано пользователем

   elsif n = 2 then
      &raise_(TOO_LARGE_VALUE,'32 кб под буфер недостаточно при чтении данных из пайпы');   --   Record in pipe too big for buffer (should not happen). Надо бросить исключение

   else
      &raise_(UNKNOWN_MODE, 'При чтении из канала сообщений возник неизвестный код ошибки: '||n);
   end if;

   return null;
end;

procedure Pipe2File(p_info varchar2) is
v$pipe   varchar2(32767);
v$file   varchar2(32767);
v$str   varchar2(32767);
v$count   number;
begin
   v$pipe := upper('debug$'||p_info);


   v$count := 0;
   loop
      utils.sleep(1);
      loop
         begin
            v$str := read_pipe(v$pipe,1);
            AppendFile(v$file,v$str);
            v$count := 0;
         exception when TIMED_OUT then
            v$count := v$count + 1;
            exit;
         end;
      end loop;

      -- Предусмотреть выход в случае если пользователь поднял монитор канала
      -- Предусмотреть выход в случае если сессия закончила работу
   end loop;
end;
begin
   -- Получаем список всех сессий, для которых НЕ запущен монитор, и которые висят в ожидании вывода в пайпу
   for   (   select w(s.[client_info] :info
         ) in v$session_wait%rowtype, (v$session%rowtype :s)
         where   lower(w.[event]) like '%pipe%put%'
            and s.[SID] = w.[sid]
            and w.[SECONDS_IN_WAIT] > 5
            and not exists(   select v(1) in v$session%rowtype
                        where   lower(v.[PROGRAM]) = 'oramon.exe'
                           and v.[ACTION] like '%'||s.[CLIENT_INFO]   )
   ) loop
      -- тут для примера запускается последовательно, на самом деле вычитка осуществляется в job. И это значит, что в запросе нужен ещё not exists из user_jobs
      Pipe2File(w.[info]);
   end loop;
end;



Текст процедуры AppendFile я опустил
Damir
Участник - экстремал


Вступление в Клуб: 29.03.2013
СообщениеПт Сен 04, 2015 08:38   Re: Как вычитать пайп другой сессии ? Ответить с цитатой
Полезность: Нет оценки
Damir пишет:
Alkov пишет:

Хм. у меня совпадает не session_id. а с CLIENT_INFO

В CLIENT_INFO цфт прописывает комбинцию из полей системной вьюшки gv$session - INST_ID, SID, SERIAL#
т.е. то, что возвращает
Код:
dbms_session.unique_session_id()

Больше для себя оставлю тут (найдено на sql.ru):
Код:

select
    sid,     to_number(substr(dbms_session.unique_session_id, 1, 4), 'xxxx') as sid_,
    serial#, to_number(substr(dbms_session.unique_session_id, 5, 4), 'xxxx') as serial#_,
    inst_id, to_number(substr(dbms_session.unique_session_id, 9, 4), 'xxxx') as inst_id_
    , dbms_session.unique_session_id
    , upper(
        lpad(to_char(sid,     'FMxxxx'), 4, '0')
      ||lpad(to_char(serial#, 'FMxxxx'), 4, '0')
      ||lpad(to_char(inst_id, 'FMxxxx'), 4, '0')     
   )  unique_session_id_
from gv$session
  where sid = (select sid from v$mystat where rownum = 1)
;
Показать сообщения:   
Ответить на тему    Клуб специалистов ЦФТ-Банк (IBSO) -> Разработка в PL/PLUS. Оптимизация запросов Oracle Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Рейтинг@Mail.ru