Модераторы: LSD
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как вовремя узнать, что данные в таблице изменилис, Как поставить слушателя на таблицу 
V
    Опции темы
ivashkanet
  Дата 5.3.2007, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: нет
Всего: 149



Всем привет.
Оракл увидел в прошлую пятницу, так что многого могу не знать. Сам пишу на .Net.

Есть небольшое приложение.
Таких приложений на разных машинах много, они по чуть-чуть (раз в 5-10 минут) изменяют эти данные.
Каждое такое приложение должно иметь актуальные данные с актуальностью, допустим, 10 сек.

Это введение, чтобы прочувствовать ситуацию smile

Для простоты пусть это будет обычная форма с DataGridView (контрол, который отображает данные в виде таблицы)
Так как данных в гриде не так уж и много (100 -200 элементов), то, в принципе, данные можно постоянно обновлять (раз в 10 сек, например). около 1000 строк забираются за 0,3 сек

Но это совсем не красиво smile

Полазил по оракловскому форуму, нашел похожую ситуацию http://forums.oracle.com/forums/thread.jsp...478&#524478

Там предложили, по сути, только одно решение:
Повесить на таблицу триггер (либо запустить в базе приложение, которое будет отслеживать изменения), который будет уведомлять приложение об изменениях в таблице.

Но я в этом совсем не особо секу. Можно здесь поподробнее?


Жду ваших ответов, ivashkanet 

P.S. Эту же тему я создал в .Net разделе, но так как люди тут и там крутятся разные, то это,ИМХО, не сильно страшно.
PM MAIL WWW ICQ   Вверх
DimW
Дата 5.3.2007, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 23
Всего: 44



Вот глава из книги, но не для недельного стажа с оракл...

Источник: Oracle для профессионалов
Автор: Том Кайт
Цитата

Пакет DBMS_ALERT
Пакет DBMS_ALERT — очень небольшой и содержит всего семь точек входа. Я опи-
шу здесь шесть наиболее интересных. Если для приложения требуется получить уведом-
ление, то наиболее существенными окажутся следующие подпрограммы.
• REGISTER. Зарегистрироваться на получение указанного сигнала. В сеансе можно
многократно вызывать подпрограмму REGISTER c разными именами сигналов,
чтобы получать уведомления при наступлении одного из нескольких событий.
• REMOVE. Снять регистрацию на получение сигнала, чтобы сервер не пытался
уведомить о наступлении события.
• REMOVEALL. Снять для сеанса регистрацию на получение всех сигналов.
• WAITANY. Ожидать уведомления о сигналах, на получение которых сеанс заре-
гистрирован. Эта подпрограмма выдает имя поступившего сигнала и обеспечива-
ет доступ к сопровождающему его короткому сообщению. Ждать можно либо за-
данное время, либо вообще не ждать (что позволяет из приложения эпизодически
опрашивать систему, чтобы узнать, не произошло ли событие, не блокируя при
этом дальнейшую обработку ожиданием события).
• WAITONE. Ожидать уведомления об указанном сигнале. Как и в случае WAITANY,
ждать можно определенное время или вообще не ждать.
Приложение, желающие послать сигнал, или уведомить о событии, может сделать это
с помощью следующей подпрограммы.
• SIGNAL. Послать сигнал о наступлении события при фиксации текущей тран-
закции. При откате посылка сигнала отменяется.
Итак, пакет DBMS_ALERT очень просто использовать. Клиентское приложение, для
которого требуется получение уведомления о событии, может содержать код вида:

tkyte@TKYTE816> begin
2 dbms_alert. register (' MyMert') ;
3 end;
4 /
PL/SQL procedure successfully completed.
tkyte@TKYTE816> set serveroutput on
tkyte@TKYTE816> declare
2 l_status number;
3 l_msg varchar2(1800);
4 begin
5 dbms_alert.waitone(name => 'MyMert',
6 message => l_msg,
7 status => l_status,
8 timeout => dbms_alert.maxwait);
9
10 if (l_status = 0)
11 then
12 'dbms_output.put_line('Сообщение события: ' || l_msg);
1564 Приложение А
13 end if;
14 end;
15 /

Мы зарегистрировались на получение сигнала MyAlert, а затем вызвали процедуру
DBMS_ALERT.WAITONE, ожидая поступление этого сигнала. Обратите внимание, что,
поскольку использована константа DBMS_ALERT.MAXWAIT из пакета DBMS_ALERT,
сеанс при выполнении этого вызова начнет ждать бесконечно. Сеанс блокируется в
ожидании соответствующего события. Можно задать для клиентского приложения пе-
риод ожидания 0 секунд, что исключит ожидание, и опрашивать сервер о наступлении
события. Например, приложение Oracle Forms может использовать ежеминутно сраба-
тывающий таймер, вызывающий процедуру DBMS_ALERT.WAITONE, чтобы узнать,
не произошло ли некоторое событие. Если событие произошло, экран приложения из-
меняется. Можно с такой же частотой активизировать поток Java, проверяющий, не про-
изошло ли событие, и обновляющий совместно используемую структуру данных, и т.д.
Чтобы послать этот сигнал, достаточно выполнить следующее:

tkyte@TKYTE816> exec dbms_alert.signal('MyMert', 'Hello World');
PL/SQL procedure successfully completed.
tkyte@TKYTE816> commit;
Commit complete.

в другом сеансе. В сеансе, заблокированном в ожидании события, вы должны немед-
ленно увидеть:
15 /
Сообщение события: Hello World
PL/SQL procedure successfully completed.
То есть сеанс больше не заблокирован. Я продемонстрировал наиболее типичный
вариант использования пакета DBMS_ALERT. Сеансы ждут сигнала с определенным
именем. Пока в пославшем сигнал сеансе транзакция не зафиксирована, уведомление о
сигнале не посылается. В этом легко убедиться с помощью двух сеансов SQL*Plus.
Работа с сигналами становится более интересной, если задаться следующими вопро-
сами.
• Что происходит, если несколько сигналов более-менее одновременно отправля-
ются разными сеансами?
• Что происходит, если посыпать сигнал несколько раз: сколько сигналов будет сге-
нерировано в конечном итоге?
• Что происходит, если более одного сеанса пошлет сигнал, после того как я заре-
гистрировался на его получение, но до вызова одной из процедур ожидания? А
что произойдет, если несколько сеансов пошлют сигнал в промежутке между вы-
зовами процедур ожидания?
Ответы на эти вопросы позволят выявить побочные эффекты использования сигна-
лов, которые необходимо учитывать. Я также предложу способы избежать некоторых
проблем, связанных со всем изложенным выше.
Пакеты DBMS_ALERT и DBMS_PIPE 1565
Одновременные сигналы нескольких сеансов
Если повторно выполнить рассмотренный пример, зарегистрировавшись на получе-
ние сигнала MyAlert и ожидая его в одном сеансе, а затем запустить два дополнитель-
ных сеанса, можно будет увидеть, что произойдет при одновременной передаче сигна-
лов из нескольких сеансов. На этот раз в обоих сеансах мы выполним:
tkyte@TKYTE816> exec dbms_alert.signal('MyMert', 'Hello World');
(транзакции не фиксируются). Окажется, что сеанс, пославший сигнал вторым, забло-
кирован. Это показывает, что если N сеансов одновременно пытаются послать один и
тот же сигнал, N-1 из них будут заблокированы при вызове DBMS_ALERT.SIGNAL.
Продолжит работу только один из сеансов. Сигналы должны посылаться последователь-
но, и следует позаботиться о предотвращении подобных проблем.
Должна обеспечиваться возможность одновременного доступа к базе данных множе-
ства сеансов. Пакет DBMS_ALERT — одно из тех средств, которое существенно сни-
жает масштабируемость по этому показателю. Если создать для таблицы триггер на со-
бытие INSERT, а в коде этого триггера использовать вызов DBMS_ALERT.SIGNAL,
при выполнении множества операторов INSERT все они выстроятся в очередь, если хоть
один сеанс зарегистрировался на получение соответствующего сигнала. Поэтому имеет
смысл ограничить количество сеансов, посылающих сигналы. Например, при получе-
нии оперативных данных из внешнего источника пакет DBMS_ALERT вполне можно
использовать, если данные в таблицу вставляет только один сеанс. Если же речь идет о
таблице проверки, в которую часто вставляют данные все сеансы, средства пакета
DBMS_ALERT лучше не использовать.
Один из способов избежать выстраивания сеансов в очередь — использовать пакет
DBMS_JOB (которому посвящен специальный раздел в этом приложении). Можно
написать процедуру, действия которой будут сводиться к передаче сигнала и фиксации
транзакции:

tkyte@TKYTE816> create table alert_messages
2 (job_id int primary key,
3 alert_name varchar2(30),
4 message varchar2(2000)
5 )
6 /

Table created.
tkyte@TKYTE816> create or replace procedure background_alert(p_job in int)
2 as
3 l_rec alert_messages%rowtype;
4 begin
5 select * into l_rec from alert_messages where job_id = p_job;
6
7 dbms_alert.signal(l_rec.alert_name, l_rec.message);
8 delete from alert_messages where job_id = p_job;
9 commit;
10 end;
11 /
Procedure created.

1566 Приложение А
Тогда соответствующий триггер будет иметь вид:

tkyte@TKYTE816> create table t (x int);
Table created.
tkyte@TKYTE816> create or replace trigger t_trigger
2 after insert or update of x on t for each row
3 declare
4 l_job number;
5 begin
6 dbms_job.submit(l_job, 'background_alert(JOB);');
7 insert into alert_messages
8 (job_id, alert_name, message)
9 values
10 (l_job, 'MyAlert', 'X в T имеет значение ' || :new.x);
11 end;
12 /
Trigger created.

И будет обеспечивать передачу сигнала фоновым процессом после фиксации. При
этом:
• сигналы посылаются в рамках транзакций;
• приоритетные процессы (интерактивные приложения) в очередь не выстраивают-
ся.
Недостаток этого подхода в том, что задания могут выполняться не сразу; может
пройти некоторое время, прежде чем сигнал будет послан. Во многих случаях это при-
емлемо (важно уведомить ожидающие процессы о произошедшем событии, даже если и
с небольшим опозданием). Средства расширенной поддержки очередей (advanced queues —
AQ) также обеспечивают хорошо масштабируемый способ уведомления о событиях в базе
данных. Использовать их сложнее, чем средства пакета DBMS_ALERT, но при этом
обеспечивается большая гибкость.
Неоднократная передача сигнала в сеансе
Теперь попытаемся ответить на вопрос, что произойдет, если послать одноименный
сигнал в приложении несколько раз, а затем зафиксировать транзакцию? Сколько сиг-
налов фактически будет послано? В данном случае ответ простой: один. Работа пакета
DBMS_ALERT аналогична механизму передачи сигналов в ОС UNlX. В UNIX сигна-
лы посылаются для уведомления процессов о событиях в операционной системе. При-
мер такого события — 'I/O is ready' (готовность к вводу-выводу), которое означает, что
один из открытых файлов (или сокетов и т.п.) готов для продолжения операций ввода-
вывода. Этот сигнал можно, например, использовать при создании сервера на основе
протоколов TCP/IP. Операционная система уведомит вас, когда в одном из открытых
сокетов появятся данные, ожидающие чтения; то есть не придется постоянно опраши-
вать состояние каждого сокета, проверяя, нет ли в нем данных для чтения. Если ОС пять
раз определила, что в сокете есть данные для чтения, но у нее не было возможности
уведомить об этом приложение, она не будет повторять сообщение пять раз. Вы полу-
Пакеты DBMS_ALERT и DBMS_PIPE 1567
чите уведомление о событии "из сокета X можно читать", но не всю хронологию преды-
дущих событий по этому сокету. Пакет DBMS_ALERT работает точно так же.
Возвращаясь к рассматриваемому примеру, можно выполнить фрагмент кода, реги-
стрирующий сеанс на уведомление о событии и вызывающий процедуру WAITONE в
ожидании этого события. В другом сеансе выполняем:

tkyte@TKYTE816> begin
2 for i in 1 .. 10 loop
3 dbms_alert.signal('MyAlert', 'Сообщение ' || i ) ;
4 end loop;
5 end;
6 /
PL/SQL procedure successfully completed.

tkyte@TKYTE816> commit;
Commit complete.

И в первом окне получаем результат:
Сообщение события: сообщение 10
PL/SQL procedure successfully completed.
Послано будет только последнее сообщение, о котором мы сигнализировали. Про-
межуточных сообщений никто никогда не увидит. Следует учитывать, что пакет
DBMS_ALERT будет, как и задумано создателями, отбрасывать все предыдущие сооб-
щения сеанса. С помощью этого пакета нельзя отправить в транзакции последователь-
ность сообщений — это только механизм сигнализации. Он позволяет уведомить кли-
ентское приложение, что "нечто произошло". Если вы предполагаете, что каждое событие,
о котором вы уведомляли с помощью сигнала, будет получено всеми заинтересованны-
ми сеансами, — вас ждет разочарование (написанный на основе этого предположения
код будет скорее всего ошибочен).
Для решения этой проблемы можно использовать пакет DBMS_JOB, если для уве-
домления о каждом событии применять его средства. Однако можно использовать и
другую технологию. С помощью средств расширенной поддержки очередей (которые в
этой книге не рассматриваются) справиться с этой задачей намного проще.
Передача многочисленных сигналов
несколькими сеансами до вызова процедуры
ожидания
Это последний вопрос: что произойдет, если сигнал будет послан несколькими се-
ансами после того, как на него поступил запрос, но прежде, чем вызвана процедура
ожидания? Аналогичный вопрос: что произойдет, если между вызовами процедур ожи-
дания несколько сеансов пошлют сигнал? Как и в случае многократного вызова
DBMS_ALERT.SIGNAL в одном сеансе, запоминается только последний сигнал, и имен-
но о нем получат уведомление сеансы. В этом можно убедиться, добавив команду PAUSE
к используемому в примерах сценарию SQL*Plus:
1568 Приложение А

begin
dbms_alert.register('MyAlert');
end;
/
pause

Затем в других сеансах вызовите процедуры DBMS_ALERT.SIGNAL с уникальны-
ми сообщениями (чтобы их можно было различать) и зафиксируйте каждое сообщение.
Например, измените представленный ранее простой цикл следующим образом:

tkyte@TKYTE816> begin
2 for i in 1 .. 10 loop
3 dbms_alert.signal('MyMert', 'Сообщение ' || i ) ;
4 commit;
5 end loop;
6 end;
7 /
PL/SQL procedure successfully completed.

После этого в исходном сеансе просто нажмите клавишу Enter, и блок кода, вызы-
вающий процедуру WAITONE, будет выполнен. Поскольку ожидаемый сигнал уже по-
слан, этот блок кода немедленно завершит работу и выдаст строку, свидетельствующую
о получении последнего сообщения (о чем оповестил сигнал). Все промежуточные со-
общения других сеансов потеряны, как и было задумано создателями пакета.
Итак, пакет DBMS_ALERT подходит для тех случаев, когда необходимо уведомить
о событиях в базе данных множество клиентов. Об этих именованных событиях должно
сообщать как можно меньше сеансов, из-за существенных проблем с очередностью до-
ступа к процедурам пакета DBMS_ALERT. Поскольку неоднократные сообщения те-
ряются, пакет DBMS_ALERT подходит в качестве средства уведомления о событии. Его
можно использовать для уведомления клиента, например, об изменении данных в табли-
це T, но попытка использовать его для уведомления об изменениях в отдельных стро-
ках таблицы T закончится неудачей (поскольку сохраняется только последнее сообще-
ние). Пакет DBMS_ALERT очень прост в использовании и практически не требует
настройки.


При использовании этого пакета оракл, не нужно будет ставить интервалы обнавления, а грид на форме будут обновляться пофакту изменения данных в БД.

Это сообщение отредактировал(а) DimW - 5.3.2007, 16:15
PM MAIL ICQ   Вверх
ivashkanet
Дата 5.3.2007, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: нет
Всего: 149



DimW, спасибо большое, буду разбираться  smile 
PM MAIL WWW ICQ   Вверх
ivashkanet
Дата 5.3.2007, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: нет
Всего: 149



Цитата(DimW @  5.3.2007,  15:05 Найти цитируемый пост)
Его
можно использовать для уведомления клиента, например, об изменении данных в табли-
це T, но попытка использовать его для уведомления об изменениях в отдельных стро-
ках таблицы T закончится неудачей (поскольку сохраняется только последнее сообще-
ние). Пакет DBMS_ALERT очень прост в использовании и практически не требует
настройки.

Понятно, нормально. С этим жить можно smile
Цитата(DimW @  5.3.2007,  15:05 Найти цитируемый пост)
Если же речь идет о
таблице проверки, в которую часто вставляют данные все сеансы, средства пакета
DBMS_ALERT лучше не использовать.
Один из способов избежать выстраивания сеансов в очередь — использовать пакет
DBMS_JOB (которому посвящен специальный раздел в этом приложении). Можно
написать процедуру, действия которой будут сводиться к передаче сигнала и фиксации
транзакции:

Хотя люди говорят что не сильно smile

Но флаг с ним smile

Цитата(DimW @  5.3.2007,  15:05 Найти цитируемый пост)
tkyte@TKYTE816> begin
2 dbms_alert. register (' MyMert') ;
3 end;
4 /
PL/SQL procedure successfully completed.
tkyte@TKYTE816> set serveroutput on
tkyte@TKYTE816> declare
2 l_status number;
3 l_msg varchar2(1800);
4 begin
5 dbms_alert.waitone(name => 'MyMert',
6 message => l_msg,
7 status => l_status,
8 timeout => dbms_alert.maxwait);
9
10 if (l_status = 0)
11 then
12 'dbms_output.put_line('Сообщение события: ' || l_msg);
13 end if;
14 end;
15 /

Я так понимаю это нужно писать в строку SQL (PL/SQL). 
Но:
1) у меня первая команда не идет  "begin 2 dbms_alert. register (' MyAlert') ;3 end;4 /" 
Цитата
identifier 'DBMS_ALERT' must be declared

У меня OracleXE. Скорее всего этого нет в нем smile Где взять?
2) Здесь описано как кидать и ловить сообщения через PL/SQL, а как ловить их из приложения? 
Или так и посылать эту команду из приложения как обычный SQL?

Еще момент: эти приложения будут уведомлять свой личный Oracle, а потом эти базы будут реплицироваться (или что-то там делать). Будет ли этот сигнал передан на все другие машины или он передастся только на эту?
Это только по требованиям независимости приложений и возможности работы в offLine


PM MAIL WWW ICQ   Вверх
LSD
Дата 6.3.2007, 00:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 18
Всего: 538



Цитата(ivashkanet @  5.3.2007,  18:36 Найти цитируемый пост)
У меня OracleXE. Скорее всего этого нет в нем  Где взять?

Нигде.

Цитата(ivashkanet @  5.3.2007,  18:36 Найти цитируемый пост)
Здесь описано как кидать и ловить сообщения через PL/SQL, а как ловить их из приложения?

Очень просто вызываешь из свойе программы функцию WAITONE или WAITANY и сессия будет заблокирована пока не истечет таймаут или не придет сообщение.

В свете того, что DBMS_ALERT в Oracle XE отсутсвует, я бы рекомендовал попробовать заменить его на UTL_TCP (если он там есть конечно).


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
ivashkanet
Дата 6.3.2007, 08:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: нет
Всего: 149



Цитата(LSD @  5.3.2007,  23:20 Найти цитируемый пост)
Нигде.

Ясно. Не очень хорошо.
Документация по XE говорит, что он все же есть:
Цитата(http://download-uk.oracle.com/docs/cd/B25329_01/doc/appdev.102/b25108/xedev_programs.htm#BABCCDFB)

List of Oracle Database XE Packages
...
Package Name  Description

DBMS_ALERT       Provides support for the asynchronous notification of database events.
...

Странно. Может его нужно как-нибудь активировать?


Цитата(LSD @  5.3.2007,  23:20 Найти цитируемый пост)
Очень просто вызываешь из свойе программы функцию WAITONE или WAITANY и сессия будет заблокирована пока не истечет таймаут или не придет сообщение.

 smile Очень smile Эта функция должна быть привязана к некоему классу. А где этот класс взять  smile Буду искать.

Нашел вот что (перерыл все пакеджи):
Цитата(http://download-uk.oracle.com/docs/cd/B25329_01/doc/appdev.102/b25108/xedev_programs.htm#BABCCDFB)

DBMS_CHANGE_NOTIFICATION
Is part of a set of features that clients use to receive notifications when result sets of a query have changed. The package contains interfaces that can be used by mid-tier clients to register objects and specify delivery mechanisms.
UTL_TCP
Provides PL/SQL functionality to support simple TCP/IP-based communications between servers and the outside world.

Т.е. есть и UTL_TCP и DBMS_CHANGE_NOTIFICATION, который, ИМХО, специально предназначен для этого.
PM MAIL WWW ICQ   Вверх
DimW
Дата 6.3.2007, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 23
Всего: 44



Цитата(ivashkanet @  6.3.2007,  08:47 Найти цитируемый пост)
Цитата(LSD @  5.3.2007,  23:20 )
Очень просто вызываешь из свойе программы функцию WAITONE или WAITANY и сессия будет заблокирована пока не истечет таймаут или не придет сообщение.


  Очень  Эта функция должна быть привязана к некоему классу. А где этот класс взять   Буду искать.


классом для WAITONE и WAITANY является пакет dbms_alert. Вот же написано - 
Цитата

dbms_alert.waitone(name => 'MyMert',
6 message => l_msg,
7 status => l_status,
8 timeout => dbms_alert.maxwait);


если в XE нет dbms_alert то WAITONE и WAITANY ты конечно же не найдешь...


Это сообщение отредактировал(а) DimW - 6.3.2007, 09:22
PM MAIL ICQ   Вверх
ivashkanet
Дата 6.3.2007, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: нет
Всего: 149



Цитата(DimW @  6.3.2007,  08:19 Найти цитируемый пост)
классом для WAITONE и WAITANY является пакет dbms_alert. Вот же написано - 

Да я вижу  smile  smile  smile  smile  smile  smile  smile  smile 
Но это в PL/SQL. А мне нужно в C#  smile  smile  smile  smile 
Цитата(ivashkanet @  5.3.2007,  17:36 Найти цитируемый пост)
2) Здесь описано как кидать и ловить сообщения через PL/SQL, а как ловить их из приложения? 
Или так и посылать эту команду из приложения как обычный SQL?


PM MAIL WWW ICQ   Вверх
DimW
Дата 6.3.2007, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 23
Всего: 44



а понял... ну от pl/sql тебе не отвертется, т.е. хранимку на нем пишешь, а как эту хранимку из C# вызвать, тебе лучше знать...

ща мож через пол часика что нить накидаю что бы было полное представление как это работает...

Это сообщение отредактировал(а) DimW - 6.3.2007, 09:50
PM MAIL ICQ   Вверх
ivashkanet
Дата 6.3.2007, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: нет
Всего: 149



Цитата(DimW @  6.3.2007,  08:42 Найти цитируемый пост)
а понял... ну от pl/sql тебе не отвертется, т.е. хранимку на нем пишешь, а как эту хранимку из C# вызвать, тебе лучше знать...

Во smile Про это я и писал выше 
DimW, не надо ничего писать. Я знаю как smile
Спасибо
PM MAIL WWW ICQ   Вверх
ivashkanet
Дата 6.3.2007, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: нет
Всего: 149



Оказалось, что у меня не было прав вызывать этот пакет.
Зашел под системным аккаунтом и все заработало smile
Надо давать привилегии запуска пакетов моему юзеру.

Вот только почему было такое дурное сообщение об ошибке  smile 
Сказали бы сразу нет прав, а то.. НЕТ ПРАВ  smile НЕТ ПРАВ  smile 
PM MAIL WWW ICQ   Вверх
DimW
Дата 6.3.2007, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 23
Всего: 44



ivashkanet,  спасибо за +  smile 
Цитата(ivashkanet @  6.3.2007,  09:54 Найти цитируемый пост)
DimW, не надо ничего писать. Я знаю как 

дык написал уже, так что не проподать же добру... мож кому нить еще понадобится...

в первую очередь нужно внимательно прочитать вот это, я по случайности опустил один из важных шагов "настройка":
источник тот же
Цитата

Настройка
Пакеты DBMS_ALERT и DBMS_PIPE стандартно устанавливаются в базе данных.
В отличие от многих стандартных пакетов, привилегия EXECUTE для этих пакетов роли
PUBLIC не предоставляется. В Oracle 8.0 и выше привилегия ЕХЕСUТЕ для этих паке-
тов предоставляется роли EXECUTE_CATALOG_ROLE. В предыдущих версиях ника-
кие привилегии на эти пакеты по умолчанию не предоставлялись.
Поскольку привилегия EXECUTE предоставлена роли, причем — не PUBLIC, вы не
сможете создать хранимую процедуру, зависящую от этих пакетов, поскольку при ком-
пиляции хранимого кода роли никогда не действуют. Необходимо явно предоставить
привилегию EXECUTE соответствующей учетной записи.



в качестве примера я взял такую схему взаимодействия:
при insert в таблицу - test_alert_tbl, нужно получить сообщение с вставленным значением.
 
приступаем к установке тестового примера.
создаем таблицу test_alert_tbl:

Код

create table TEST_ALERT_TBL
(
  NAME VARCHAR2(10)
)


затем создаем триггер для этой таблицы, он то и будет давать отчет о вставленной записи:
Код

create or replace trigger do_alert
  after insert on test_alert_tbl  
  for each row
begin
    -- говорим что событие произошло
    dbms_alert.signal('insert_alert', :new.name);
end do_alert;


теперь создаем процедуру для получения события, о котором говорит нам триггер:
Код

create or replace procedure return_alert(val out test_alert_tbl.name%type) is
  l_status number;
  l_msg test_alert_tbl.name%type;
begin
  -- регистрируемся на событие
  dbms_alert. register ('insert_alert');
  
  -- переходим к ожиданию события
  dbms_alert.waitone(name => 'insert_alert',
                     message => l_msg,
                     status => l_status,
                     timeout => dbms_alert.maxwait);
  val := l_msg;
end return_alert;


все, теперь можно тестировать.
запускаем нашу процедуру - ждунчика события:
Код

begin
  return_alert(val => :val);
end;

сессия переходит в "ждущий режим"... т.е. ждет когда произойдет событие под названием "insert_alert"

теперь можно спокойно открыть новую сессию и вставить значение в поле name нашей таблицы.
после вставки наша процедура прекратит работу и возвратит значение вставленной записи.



Это сообщение отредактировал(а) DimW - 6.3.2007, 11:21
PM MAIL ICQ   Вверх
ivashkanet
Дата 3.4.2007, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: нет
Всего: 149



Всем еще раз спасибо. 

Чисто для .Net существует замечательный класс OracleDependency Class
Я еще с ним не сильно разбирался, но тесты он прошел на ура smile
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Oracle"
Zloxa
LSD

Данный раздел предназначен для обсуждения проблем с Oracle Database, другие продукты Oracle здесь не обсуждаются. Просьба при создании темы, придерживаться следующих правил:

  • при создании темы давайте ей осмысленное название, описывающее суть проблемы
  • указывайте используемую версию базы, способ соединения и язык программирования
  • при ошибках обязательно приводите код ошибки и сообщение сервера
  • приводите код в котором возникла ошибка, по возможности дайте тестовый пример демонстрирующий ошибку
  • при вставке кода используйте соответсвующие теги: [code=sql] [/code] для подсветки SQL и PL/SQL кода, [code=java] [/code] - для Java, и т.д.

  • документация по Oracle: 9i, 10g, 11g
  • книги по Oracle можно поискать здесь
  • действия модераторов можно обсудить здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, LSD.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Oracle | Следующая тема »


 




[ Время генерации скрипта: 0.0696 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.