Доброго времени суток, коллеги. При интеграции BPM с внешней БД возникла необходимость вставлять даннные из карточки BPM в таблицу на связанном сервере (Firebird 2.0). Для работы с таблицами связанного сервера содали представления. С селектами из этих представлений никаких проблем не было. Но вот с инсертами и апдейтами возникла проблемка - после инсерта(апдейта или делита) транзакции подвисали минут на 5 и выполнить очередной запрос к этому представлению было невозможно. Нашли выход из этой ситуевины:
1. Создали на связанном сервере хранимую процедуру (пишет данные в таблицу и возвращает одно значение).
2. На sql сервере в представлении создали триггер который срабатывает на инсерт, пинает хранимку на связанном сервере и передает параметры в эту хранимку.
3. В карточку BPM добавили кнопку и повесили на нее скрипт которые инсертит данные из полей карточки в представление.
После данные манипуляций все работает отлично, данные инсертятся, транзакции не подвисают.
Но вот возник вопросик. Как я написал в первом пункте, хранимка возвращает одно значение и мы не можем приложить ума как его перехватить чтобы вернуть это значение в текстовое поле в карточку BPM. Ниже код хранимки, триггера и скрипта инсерта.
Код хранимки.
BEGIN
INSERT INTO NAPRAVLENIE(NAPRAVLENIE.NAPRAVLENIE_NUM,NAPRAVLENIE.USLUGA_1) VALUES (:NUM,:U1);
NEW_OUTPARAM=gen_id(BP_GEN,1);
SUSPEND;
END
Код триггера.
USE[BPMonline]
GO /****** Object: Trigger [dbo].[IOI_napr] Script Date: 03/11/2015 17:56:44 ******/ SET ANSI_NULLS ON
GO SET QUOTED_IDENTIFIER ON
GO ALTERTRIGGER[dbo].[IOI_napr]ON[dbo].[napr]
INSTEAD OF INSERT AS
BEGIN
declare @U1 varchar(250)
declare @NUM varchar (250)
declare @NAP_NUM varchar (250) SET @U1=(SELECT i.USLUGA_1 FROM inserted i) SET @NUM=(SELECT i.NAPRAVLENIE_NUM FROM inserted i)
execute ('select * from BP_nap_ins('''+@NUM+''','''+@U1+''')') at DMS
END;
Код скрипта инсерта кнопки.
var U1=Page.TextEdit5.Value;// для теста передаем только 1 значение
var insert =new Insert(UserConnection).Into("napr").Set("USLUGA_1", Column.Parameter(U1)).Execute(); returntrue;
если вы полнить инсерт из sql менеджера то в результах я вижу, что хранимка вернула значение.
каким оброзом можно запихнуть возвращаемое значение в переменную и использовать ее дальше в BPM ?
Спасибо что дочитали :)
Спасибо за ответ, пошли немного другим путем. Запихнули текст триггера еще в одну хранимку, и через OPENQUERY пнули хранимку на связанном сервере. Таким макаром удалось вернуть значение в переменную. Сейчас бытаюсь разобраться как вызвать хранимку из формы.
может кому не сложно написать коды вызова хранимки:
в хранимку передаем значение из поля TextEdit5.
вернуть значение нужно в TextEdit14
USE BPMonline;
IF OBJECT_ID ('dbo.BPM_to_DMS', 'P') IS NOT NULL
DROP PROCEDURE dbo.BPM_to_DMS;
GO
CREATE PROCEDURE dbo.BPM_to_DMS
@U1 varchar(250),
@NAP_NUM varchar (250) OUTPUT
--@U2 varchar (250)
AS
SET NOCOUNT ON;
set @NAP_NUM =(select * from OPENQUERY (dms,'select * from BP_nap_ins(''+@U1+'')'))
GO
итак, удалось запустить хранимку, передать ей значение в U1, но никак не могу разобраться как вернуть из нее значение в TextEdit14. необходимое значение возвращается в NAP_NUM.
код вызова хранимки:
var U1=Page.TextEdit5.Value;//var NAP_NUM;
var dataValueTypeManager =(DataValueTypeManager)UserConnection.AppManagerProvider.GetManager("DataValueTypeManager");
var storedProcedure =new StoredProcedure(UserConnection, "BPM_to_DMS");
storedProcedure.WithParameter(U1);
storedProcedure.WithOutputParameter("NAP_NUM", dataValueTypeManager.GetInstanceByName("Text"));using(DBExecutor dbExecutor = UserConnection.EnsureDBConnection()){
dbExecutor.StartTransaction(System.Data.IsolationLevel.ReadUncommitted);
storedProcedure.Execute(dbExecutor);
dbExecutor.CommitTransaction();}//Page.TextEdit14.SetValue(NAP_NUM);returntrue;
можно хотябы пример похожий (в примере с поиском дублей ничего не понятно)
PS: когда все допилю обещаю написать полный мануал по вызову хранимой процедуры на связанном сервере firebird 2.0
Добрый день. А почему Вы не используете тот пример, что я вам скинул? Им тоже можна "дергать" хранимые процедуры и получать значения
извиняюсь, но я не понял что вы в своем примере делаете и как его можно применить к моей хранимке, если вам не слложно, не могли бы вы написать свой пример с коментами или подогнать егео под мою хранимку?
там все очень просто. UserConnection - Переменная которая хранит в себе параметры подключения.
sqlText - сюда можно запихнуть любой SQL запрос, в том числе и вызов хранимой процедуры.
while (dr.Read()) {
PreviousMonth = dr.GetValue(0).ToString();
}
"dr" - сохраняет в себе структуру возвращенных данных
PreviousMonth - это локальная переменная, которая создается и туда записывается значение. Можете вместо этого кода вписать
следующий код
Page.TextEdit14.SetValue(dr.GetValue(0).ToString());
только вместо "0" подставте нужный индекс. Посмотрите какой он по счету в выборке в запросе
скрипт отрабатывает но в TextEdit14 ничего не возвращает(пробовал разные индексы(0 1 2), а вообще запись по счету первая).
вот текст скрипта, вашим методом я так и не разобралмя как вызвать хранимку с передачей в нее параметров.
var U1=Page.TextEdit5.Value;//var result = 5;
var dataValueTypeManager =(DataValueTypeManager)UserConnection.AppManagerProvider.GetManager("DataValueTypeManager");
var storedProcedure =new StoredProcedure(UserConnection, "BPM_to_DMS");
storedProcedure.WithParameter(U1);
storedProcedure.WithOutputParameter("NAP_NUM", dataValueTypeManager.GetInstanceByName("Text"));using(var dbExecutor = UserConnection.EnsureDBConnection()){
dbExecutor.StartTransaction(System.Data.IsolationLevel.ReadUncommitted);// storedProcedure.Execute(dbExecutor);{using(var dr =storedProcedure.ExecuteReader(dbExecutor)){while(dr.Read()){
Page.TextEdit14.SetValue(dr.GetValue(0).ToString());}}}
dbExecutor.CommitTransaction();}returntrue;
Профайлер перехватывает выполнение и показывает что в @NAP_NUM вернулось нужное значение
Вы не коректно написали, UI Надо писать без кавычек, это имя переменной, в которой хранится значение передаваемой в хранимку переменной.
Владимир, если написать таким образом то просит объявить переменную NAP_NUM, если ее объявить то просит записать туда какаое-нить значение. Если передать туда 2 значения то процедура не срабатывает т.к. в процедуре ожидается 1 параметр входящий и 1 исходящий, а таким образом мы передаем туда 2 входящих. Может подскажите каким образом обявить NAP_NUM исходящим параметром? Спасибо.
В качестве параметров я привел пример. Вы можете их вообще туда не передавать, или передать сколько угодна. Вы передайте, те переметры, что Вам надо
var Proc = string.Format("BPM_TO_DMS {0},{1} ...", "U1", "NAP_NUM", ...);
Владимир, это я понял, но мне нужно передать в хранимку 1 параметр, и хранимка должна вернуть 1 параметр. для этого в хранимке объявлен переменная NAP_NUM OUTPUT (в которую возвращается результат работы хранимки). елси вызывать хранимку через var proc =new StoredProcedure то там можно указать какой из параметров входящий а какой выходящий. Может вы подскажете каким образом в вашем скрипте указать что NAP_NUM это OUTPUT параметр? спасибо за помощь