Как реализовать нормально и просто, вызов хранимке в возвратом данных в клиент.
Сервер MS SQL 2008R2 , Террик CRM 3.4 или Distrubution 3.4.1

Нравится

3 комментария

Из хранимой функции точно можно.

попробуйте использовать сервис CustomQuery

Через СustomQuery это очень кривой вариант, особенно если учесть что вернуть надо набор данных из несколько сот тысяч записей.

Показать все комментарии

Часто в работе на проектах необходимо использовать вызов хранимых процедур SQL из скриптов Terrasoft. В случаи вызова процедур в одном/двух случаях можно описать вызов вручную, когда же таких вызовом множество их описание становится нудным даже при условии копипаста.

Из этого родился перечень функций для вызова процедур. Возможно, код не идеален, но помог избежать некоторых механических описаний, кому-то они (функции) тоже могут оказаться полезны.
Во вложении сервис, содержащий описанные ниже функции.

Описание функций:
ExecuteSQL(SQLText, Names, Types, Values) - выполняет SQL скрипт с указанными параметрами
• SQLText - текст SQL скрипта
• Names - массив имен параметров
• Types - массив типов параметров, в соответствии с порядком следования элементов параметра Names
• Values - массив значений параметров, в соответствии с порядком следования элементов параметра Names

ExecuteSQLWithoutParameters(SQLText) - выполняет SQL скрипт без указания параметров
• SQLText - текст SQL скрипта

ExecuteSQLWithReturnParameter(SQLText, Names, Types, Values, ReturnName) - выполняет SQL скрипт с указынными параметрами и возвращает результат
• SQLText - текст SQL скрипта
• Names - массив имен параметров
• Types - массив типов параметров, в соответствии с порядком следования элементов параметра Names
• Values - массив значений параметров, в соответствии с порядком следования элементов параметра Names
• ReturnName - название возвращаемого параметра

Коды функций:

function ExecuteSQL(SQLText, Names, Types, Values) {
        var Parameters = CreateSPParameters();
        var i = 0;
        while (i Names.length) {
                CreateSPParameter(Parameters, Names[i], Types[i], Values[i]);
                i++;
        }
        Connector.DBEngine.ExecuteCustomSQL(SQLText, Parameters);
}

function ExecuteSQLWithoutParameters(SQLText) {
        Connector.DBEngine.ExecuteCustomSQL(SQLText, System.EmptyValue);
}

function ExecuteSQLWithReturnParameter(SQLText, Names, Types, Values, ReturnName) {
        var Parameters = CreateSPParameters();
        var i = 0;
        while (i Names.length) {
                CreateSPParameter(Parameters, Names[i], Types[i], Values[i]);
                i++;
        }
        Parameters.ItemsByName(ReturnName).ParamType = 1;
        Connector.DBEngine.ExecuteCustomSQL(SQLText, Parameters);
       
        var Result = Parameters.ItemsByName(ReturnName).ValAsInt;
        return Result;
}

Примеры использования:

var SQLText = 'CheckCardSelectingOffering :OfferingInWarehouseID, ' +
             ':CardSelectionID, :ReturningCustomer, :CancelSelection, :Result OUTPUT';
var Names = new Array('OfferingInWarehouseID', 'CardSelectionID',
             'ReturningCustomer','CancelSelection', 'Result');
var Types = new Array(pdtGUID, pdtGUID, pdtGUID, pdtGUID, pdtInteger);
var Values = new Array(OfferingDataset('ID'), CardSelectionID, wartypReturningCustomer,
             wartypCancelSelection, 0);
var Result = ExecuteSQLWithReturnParameter(SQLText, Names, Types, Values, 'Result');

var SQLText = 'CalcAccountAmounts :AccountID, :Held, :CardSelection, ' +
           ':Platezh, :Paid';
var Names = new Array('AccountID', 'Held', 'CardSelection', 'Platezh', 'Paid');
var Types = new Array(pdtGUID, pdtGUID, pdtGUID, pdtGUID, pdtGUID);
var Values = new Array(AccountID, warstateHeld, wartypCardSelection, doctypePlatezh,
           docstatPaid);
ExecuteSQL(SQLText, Names, Types, Values);

Нравится

Поделиться

0 комментариев
Показать все комментарии

Существует ли в террасофт возможность вызова хранимых процедур для Oracle? Пытался использовать примеры с форума, используя ExecuteCustomSQL, но параметры не только не возвращаются, но даже не передаются в процедуру.

var Parameters = CreateSPParameters();
CreateSPParameter(Parameters, 'ID', pdtString, '1111111111111111');
CreateSPParameter(Parameters, 'POUT', pdtInteger, 0);
Parameters.ItemsByName('POUT').ParamType = 1;

тут Parameters.Items(0).Value в дебагере нормально '1111111111111111'
Parameters.Items(1).Value тоже нормально - 0

var SQL = 'BEGIN TSCRM.pa2_check_tbl_account(:ID,:POUT); END;';
Connector.DBEngine.ExecuteCustomSQL(SQL, Parameters);

После ExecuteCustomSQL в Parameters значение всех параметров неопределено.
При этом процедура запускается, raise оттуда идет, но raise_application_error (-20001, 'PID '||ID);
ID не вернет.

вот процедура:

create or replace procedure pa2_check_tbl_account
(
ID in "tbl_Account"."ID"%type,
POUT in out number
) is

begin
POUT := 5;
raise_application_error (-20001, 'PID '||ID);
end;

что не так?

Нравится

2 комментария

Илья, попробуйте запрос заменить на:

var SQL = 'BEGIN TSCRM.pa2_check_tbl_account(:pID,:pPOUT); END;';

Больше ничего не меняйте!

Огромное спасибо. Вчера весь день убил, пытаясь найти в чем ошибка. Теперь все получилось.

Показать все комментарии

Доброго времени суток!
У меня следующий вопрос, есть БД, находиться на другом сервере, в ней есть хранимая процедура, для запуска в которую необходимо передавать входные параметры и отобразить выборку которую она вернет. Редактирование данных выборки не требуется. Можно ли это как-то реализовать в Террасофте.

Нравится

15 комментариев

Может через ADO. Есть соответствующий сервис. Или написать хранимку на сервере TSCRM, вызывать ее, а она уже пусть лезет на второй сервер.

Можно.
1. Почитать про Linked Server и DTS (sql.ru)
2. Реализовать функционал.
3. Запуск делать из Террасофта(ExecuteCustomSQL, например).

Ссылки, которые помогут.
http://www.sql.ru/forum/actualthread.aspx?bid=1&tid=186686
http://www.sql.ru/forum/actualsearch.aspx?search=openquery&sin=0&a=&ma=…

Реализовывать такие вещи лучше на уровне СУБД. В зависимости от используемой БД решение может быть различным. Советую заглянуть на SQL.ru

На сколько я поняла, то сохранять полученные от хранимки данные никуда не нужно, только отобразить. Мне кажется, лучше с ADODataset использовать потому, что его сразу можно использовать в окне с гридом для отображения. А если через linked server на стороне нашего сервера вызывать ее, то придется еще думать, куда результат потом класть.

"Раловец Ольга" написал:А если через linked server на стороне нашего сервера вызывать ее, то придется еще думать, куда результат потом класть.

С linked server так же. Просто SQl текст для ADODataset будет вида exec [RemoteServer].[RemoteDB].[dbo].[MyStoredProc] ...
Если без него, придется прописывать ConnectionString для удалленого сервера...

Разница в том, что при использовании ADODataseta результаты сразу из него можно отображать в окне. Если Вы просто выполните exec [RemoteServer].[RemoteDB].[dbo].[MyStoredProc] ..., то нужно как-то их будет еще донести до пользователя, пользователь же не в QueryAnalyzere работает.

"Раловец Ольга" написал:то нужно как-то их будет еще донести до пользователя

эм... у ADODataset есть свойство Текс SQL... туда пишем валидный вызов хп(в нашем случае - вызов с удаленного сервера), определяем поля для результата выполнения того чего мы написали и вяжем на грид...
Я как раз говорил об использовании ADODataset со стороны Террасофта + Linked Server со стороны СУБД.

"Доленко Юрий" написал:Я как раз говорил об использовании ADODataset со стороны Террасофта

Ну и я о том же :) А насчет ConnectionString, думаю, не принципиально.

Вызвать то как понятно..а как в нее параметры передать при вызове? чтоб пользователь их мог ввести?
ЗЫ
я просто новичек..

Не устаю давать ссылку на этот пост :smile:
http://community.terrasoft.ua/blogs/2171

"Кирилл Игоревич" написал:Вызвать то как понятно..а как в нее параметры передать при вызове? чтоб пользователь их мог ввести?

Пусть пользователь вводит в каком-нибудь окошке, а передавать можно перед открытием датасета. В сервисе ADODataset можно создать несколько параметров, в тексте SQL обращаться к ним :ParamName, а заполнять значения так:

ADODataset.Parameters.ItemsByName('ParamName').Value = ParamValue;

На самом деле задача проста, есть процедуры которые возвращают датасеты, это отчеты...мне требуется понять получиться ли отобразить эти отчеты в террасофте с использованием репортера встроенного в Terasoft. А с самим терасофтом я не сильно знаком поэтому и спрашиваю всякие простые вещи))

"Глова Сергей" написал:Не устаю давать ссылку на этот пост

там как-то много кода )
Вот Ольга предложила, на мой взгляд, самый правильный вариант решения.
"Кирилл Игоревич" написал:репортера встроенного в Terasoft.

Лично я бы, FastReports не касался бы и 10-ти метровой палкой. Там очень плохой експорт в Word/Excel.
Получайте выборки в ADODataset и выкладывайте в ворд или ексель. Хотя если нужно просто отправить на печать - то и Fast сгодится.

"Доленко Юрий" написал:Вот Ольга предложила, на мой взгляд, самый правильный вариант решения.

А я и не спорю, что с ADO в данном случае будет проще.:smile: Просто о ExecuteCustomSQL знать надо обязательно.

Именно этот вариант я и использовал))))
Спасибо большое Ольге...и все кто помогал.

Показать все комментарии