Вход | Регистрация


1С:Предприятие :: 1С:Предприятие 8 общая

Подскажите по хранимым процедурам через ADODB

Подскажите по хранимым процедурам через ADODB
Я
   Euroset1
 
23.03.18 - 12:48
База ORACLE
Умею вызывать хранимые функции, возвращающие обычный тип. Причем как через OUT параметр, так и через стандартный ретурн.

Сам заголовок функции для примера:
CREATE OR REPLACE FUNCTION BOSS.UPDATEDOC1C
  ( p_IO_ID IN BOSS.INVOICE.IO_ID%TYPE,
    p_Status IN BOSS.INVOICE.DOCOUT%TYPE )

  RETURN  NUMBER IS
       n_Id BOSS.INVOICE.ID%TYPE;
       n_Type  NUMBER(1);

А теперь код ее вызова, который работает:
                Команда                     = Новый COMОбъект("ADODB.Command");
                Команда.ActiveConnection      = Соединение;
                Команда.CommandText          = "boss.updatedoc1c";
                Команда.CommandType         = 4;// stored proc

                
                Парам1                        = Команда.CreateParameter("p_IO_ID", 4, 1);
                Парам2                        = Команда.CreateParameter("p_Status", 3, 1);
                Возвратка                     = Команда.CreateParameter("result", 4, 4);  // 4 тип - флоат сингл, 4 тип параметра - возвратка

                
                Команда.Parameters.Append(Возвратка);
                Команда.Parameters.Append(Парам1);
                Команда.Parameters.Append(Парам2);
                
                Парам1.Value                = Число(ГИД);
                Парам2.Value                = СтатусПодписания;
                
                Команда.Execute();
                
                Сообщить(Возвратка.Value = 0);

Как видите, несмотря на то, что возвратка не прописана как OUT параметр, но объявлять ее в параметрах все равно приходится (причем пофиг с каким именем...). И так все работает.

А мне нужно теперь из другой функции вернуть рекордсет (таблицу). Согласно статьи http://www.askit.ru/custom/vba_office/m9/09_06_ado_command.htm и где-то подобной статьи с самого Майкрософта, это сделать МОЖНО. Но вот как - фиг его знает, помогите плиз.

Проблемы, которые ловлю при разных попытках:
1) Если использую Parameters.Refresh(), то он почему-то не работает. Хотя все сделал к в документации, видно вопросы к провайдеру
2) Если вообще не описываю возвратку, то ругается при выполнении, что мол не найдена такая процедура (ясен пень, ведь это функция.). То есть он явно намекает, что возвратка должна быть описана
3) Пробовал разные типы для возвратки - ну не хочет, понятное дело. Ну нету там типа Recordset в перечне...
4) Кто-то скажет вместо StoredProc использовать SELECT * FROM TABLE(boss.updatedoc1c(444,11)), но увы, этот способ не работает с данной функцией, ибо она делает апдейты и оракл будет ругаться на такую попытку (если бы она чисто селектила, то без проблем конечно).

Как же мне всетаки получить этот несчастный рекордсет, используя StoredProc? Как задекларировать этот параметр возвратка вручную?
 
 
   karabas11
 
1 - 23.03.18 - 13:01
А в чем вопрос? Так много текста, ничего понять нельзя.
   Euroset1
 
2 - 23.03.18 - 13:07
(1) Желаемый результат - получить таблицу, возвращаемую хранимой оракловой функцией при помощи ADODB с параметром CommandType = 4 (StoredProc).
   karabas11
 
3 - 23.03.18 - 13:15
(2) RecordSet = Command.Execute(); 
Неужто не работает?
   Euroset1
 
4 - 23.03.18 - 13:49
(3) конечно не работает. Почему - я описал в "много текста".
   karabas11
 
5 - 23.03.18 - 14:43
(4) Команда.CommandType         = 8; // а как обычный селект?
   Euroset1
 
6 - 23.03.18 - 14:44
(5) "4) Кто-то скажет вместо StoredProc использовать SELECT * FROM TABLE(boss.updatedoc1c(444,11)), но увы, этот способ не работает с данной функцией, ибо она делает апдейты и оракл будет ругаться на такую попытку (если бы она чисто селектила, то без проблем конечно)."

Цитата из (0).
   karabas11
 
7 - 23.03.18 - 15:46
(6) насколько я понял, вы сами в оракле пишете. Попробуйте не смешивать апдейт с селектом.

RETURN  NUMBER IS  - а не тут ли проблема? Хочется верить, что тут вместо намбера должна таблица возвращаться
https://oracle-base.com/articles/misc/pipelined-table-functions
   Euroset1
 
8 - 23.03.18 - 15:55
(7) Я не пишу в оракле, просто есть определенные базовые возможности. Код оракловый просто стянул из девелопера. Там намбер стоит потому что функция из примера возвращает число и делает это хорошо. Я как раз акцентировал на том, что в таком виде она работает. А мне теперь нужно вместо намбера вернуть таблицу (уже другая функция).

TYPE GOODS_RECORD IS RECORD (
     IDCODE BOSS.GOODSDETAIL.IDCODE%TYPE,
     NAME BOSS.DEPOTS.NAME%TYPE,
     UNIT BOSS.GOODSDETAIL.UNIT%TYPE,
     RESERV BOSS.GOODSDETAIL.RESERV%TYPE,
     LAYPUT BOSS.GOODSDETAIL.LAYPUT%TYPE
    );

    TYPE GOODS_TABLE IS TABLE OF GOODS_RECORD;

FUNCTION GET_GOODS_LIST (
  ARTICUL_IN BOSS.CATALOGS.ARTICUL%TYPE, SUPPLIER_IN BOSS.CATALOGS.SUPPLIER%TYPE  
) RETURN GOODS_TABLE parallel_enable pipelined;
   VitShvets
 
9 - 23.03.18 - 16:01
(0) Я, правда с MS-SQL, в таких случаях вместо ADODB.Command пользую ADODB.Recordset:
   RS = Новый COMОбъект("ADODB.Recordset");
   RS.ActiveConnection = Connection;
   RS.Open(ТекстЗапроса);
   Euroset1
 
10 - 23.03.18 - 16:23
(9) рекордсет не позволяет выполнить хранимую процедуру или функцию напрямую - она только запрос дает выполнить. А мне в запросе нельзя, потому что на запрос с участием данной функции будет ругаться - она изменяет данные.
 
 Рекламное место пустует
   VitShvets
 
11 - 23.03.18 - 17:04
(10) Не правда. У меня нормально отрабатывает:
ТекстЗапроса = "SET DATEFORMAT ymd
     |DECLARE @StartDate datetime = #StartDate#
     |DECLARE @EndDate   datetime = #EndDate#
     | EXEC dbo.spGetMovements @StartDate, @EndDate";
   VitShvets
 
12 - 23.03.18 - 17:08
(11) + к (12) И вот такое отрабатывает:
    |INSERT INTO
    |    ИмяТаблицы
    |    (Текст_INTO)
    |VALUES Текст_VALUES
    |
    |SELECT @@ROWCOUNT AS InsertCount
   int32i
 
13 - 23.03.18 - 18:16
   Euroset1
 
14 - 23.03.18 - 18:32
(13) cmd1.Parameters.Refresh у меня к сожалению не работает, о чем я писал выше. При попытке потом обратиться к параметрам вылезает ошибка выполнения, связанная с неправильным индексом. Каунт по коллекции параметров показывает ноль записей.
Причем в мануале написано, что рефреш не отрабатывает, если не задали соединение, тип команды или текст команды. У меня все это задано.
   Euroset1
 
15 - 23.03.18 - 18:33
(12) Речь идет о хранимой функции, возвращающей таблицу после того, как она же выполняет в ней изменения.
   Euroset1
 
16 - 23.03.18 - 18:35
(13) Причем самое интересное, что для не табличного возвратного параметра я нашел решение - я его просто объявил как аут параметр с произвольным именем. А как мне объявить вместо числа таблицу, учитывая дефицит типов, предлагаемых на выбор, непонятно.
   VitShvets
 
17 - 23.03.18 - 18:57
(15) В (11) процедура как раз возвращает таблицу.
(16) Оракл я не щупал, а не разрешает он делать по принципу (12)? Скармливаешь АДО не одну команду, а последовательность. Последней командой выполняешь select, дабы получился нужный recorset. У сиквела работает.
   Euroset1
 
18 - 23.03.18 - 22:23
(17) Касаемо (10), не должно работать для описанной мной функции. А именно: для такой функции, которая выполняет апдейт, а потом еще и возвращает таблицу. При попытке выполнить твой запрос оракл вывалит ошибку, что "нельзя использовать апдейт в селекте".

Касаемо замены одной команды пакетом - не выйдет. Дело в том, что функция призвана компенсировать тот факт, что !с-юзеру не хотят давать гранты даже на чтение. Именно поэтому идет переход на хранимки и вьюхи. Для этого мне и нужно вызывать хранимку именно как хранимку, а не как текст запроса.
   Euroset1
 
19 - 24.03.18 - 15:10
Для оракла ведь тоже разные провайдеры бывают. Тот, что у меня, похоже менее функционален по хранимкам.
Oracle in OraClient11g_Home2 у меня ((
   Euroset1
 
20 - 26.03.18 - 21:25
Может есть какие-то альтернативы ADODB?
   VitShvets
 
21 - 26.03.18 - 22:19
(20) АДО в данном случае "шлюз" между 1С и СУБД. Что разрешает СУБД, то сможет 1С выполнить через. ИМХО, надо копать в написание такой хранимой процедуры на стороне СУБД, дабы "делала всё хорошо, возвращая нужный рекордсет". АДО это будет или иные способы взаимодействия с БД, ничего не изменится.
   VitShvets
 
22 - 26.03.18 - 22:22
(20) Кстати, как совсем костыльный вариант, не возвращать в данном вызове RS, а писать в какую-нибудь общедоступную табличку типа "#MyTmpTable" или "##MyTmpTable". А затем, отдельным запросом, читать "MyTmpTable" с получением уже RS.


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует