Имя: Пароль:
1C
1С v8
Как вернуть значение из Хранимой процедуры
0 rudava
 
08.12.20
20:32
Доброго времени суток Форумчане!

Есть процедура в форме обработки  конфигурации 1с цель которой является:
1 Передача параметров в хранимую процедуру БД ms sql и ЕЁ выполнение с внесенными параметрами;
2 Получение сообщения из процедуры через параметр @msg назад в виде сообщения!

нужен пример кода как получит назад сообщение из процедуры, которое генерится в ходе выполнения ХП

Процедура примерно такая:
Процедура ПередатьВSCADAизДокумента(GUIDДокуменнта,НомерДокументаВSCADA)
      ИмяСервераSQL = "192.168.1.10,1441";
    ПользовательSQL = "SA";
    ПарольSQL = "parol";
    БазаДанныхSQL = "NewBD";
    ХранимаяПроцедураSQLSQL =  "docProvercaSclada";

    //Подключение к SQL-серверу
    
    Попытка
        Соединение  = Новый COMОбъект("ADODB.Connection");
        Команда     = Новый COMОбъект("ADODB.Command");
        Выборка     = Новый COMОбъект("ADODB.RecordSet");
        Соединение.ConnectionString =
            "driver={SQL Server};" +
            "server="+ИмяСервераSQL+";"+
            "uid="+ПользовательSQL+";"+
            "pwd="+ПарольSQL+";"+
            "database="+БазаДанныхSQL+";";
        Соединение.ConnectionTimeout = 30;
        Соединение.CommandTimeout = 600;
        //Открытие соединение
        Соединение.Open();
        Команда.ActiveConnection   = Соединение;
        Сообщить("Успешное подключение!");
    Исключение
        Сообщить(ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    // ******Обход табличной части накладной *********
    
        Для каждого ТабСтр Из Объект.ТЧнакладные  Цикл
            

        GUID = "Null"; //GUIDДокумента;
        Since = ТабСтр.НачалоПоставки;
        Till =  ТабСтр.КонецПоставки;
        Docnum = НомерДокумента;
        sklad   = НомерСклада;         
        skladtype = ВидСклада;
        partNo  = НомерПартии;
        nomnum   =  НомерНоменклатуры;
        MSG = "Null";
        PN = НомерСертификатаКачества;
                    

ТекстТекущейИнструкции = "EXEC "+ХранимаяПроцедураSQL+" "+GUID+","+Since","+Till+","+
","+docnum+","+sklad +","+skladtype+","+partNo+","+Nomnum+","+msg+","+pn+"";
    Попытка
        Соединение.Execute(ТекстТекущейИнструкции,,128);
     Исключение
            Сообщить(ОписаниеОшибки());
    КонецПопытки;
    
    КонецЦикла;
КонецПРоцедуры


В хранимой процедуре убрал многое, так как листинг большой и замысловатый, но суть осталась!
//*************Хранимая процедура******************
ALTER procedure [dbo].[docProvercaSclada] (@doc uniqueidentifier output,
@since datetime, till datetime, @docnum varchar(20),
@sklad int, @skladtype int, @partnum int, @nomnum bigint,
@msg varchar(500) output,
@pn varchar(20) = null
)
Если @since  = 0 then
@msg = "Заполните начальную дату и повторите операцию"

Если till datatime = 0 then
@msg = "Заполните конечную  дату и повторите операцию"

Если @docnum datatime = 0 then
@msg = "Заполните конечную  дату и повторите операцию"

если все нормально
insert into docSklad(doc, sklad, tovar, scladtype, wight, partNo)
       values(@doc, @sklad, @tovar, @scladtype, @wight, @partNo)

Нужен пример кода или внятное объяснение как получить из ХП "отзыв"

как передать понятно, как выбрать понятно, а как передать и получить назад нет!
1 ДенисЧ
 
08.12.20
20:37
2 youalex
 
08.12.20
20:47
просто select`ом из хранимки не вариант возвращать?
или прямо хочется с параметрами в ADO заморочиться?
3 rudava
 
08.12.20
22:38
ну мне же сначала туда что то скормить нужно
а назад получить, вот как это в коде оформить
4 youalex
 
08.12.20
23:03
туда - в общем случае можно литералами передать (совсем в общем - через xml строку)
типа такого:
ТекстКоманды = СтрШаблон("EXEC _testrpoc @par1 = '%1', @msg='%2'", ТекущаяДата(), "исх.сообщение");
Команда.CommandType = 1;
Команда.CommandText = ТекстКоманды;

обратно - в хранимке пишешь в последнем резалте (в конце тела процедуры) что-то типа
SELECT @msg AS msg

и через ADODB.RecordSet уже стандартно его ловишь в 1С:

НаборАДО = Команда.Execute ();
Если НЕ НаборАДО.EOF() Тогда
ПолеАДО = НаборАДО.Fields(0);
Сообщить(СтрШаблон("%1 = %2", ПолеАДО.Name,  ПолеАДО.Value));    
КонецЕсли;
5 youalex
 
09.12.20
09:44
+ можно еще извратиться, и выполнить пакетный (здесь по сути динамический) запрос через exec, примерно так:

ТекстКоманды = СтрШаблон("exec ('declare @msg nvarchar(10) = ''%1'';exec _testrpoc @par1 = ''%2'', @msg=@msg output; select @msg msg')", ТекущаяДата(), "исх.сообщение");
6 rudava
 
09.12.20
11:02
Второй вариант, так как нельзя ничего менять на стороне SQL (политика однако).
в profiler вижу прилетела инструкция, все так EXEC парам1, Парам2... и в конце, select (формирует таблицу)
как забрать  ЭТО в 1с
7 youalex
 
09.12.20
11:17
(6) в (4)  , начиная с "и через ADODB.RecordSet"
https://www.script-coding.com/ADO.html в помощь
8 rudava
 
09.12.20
20:54
Спасибо Youalex, все сложилось, очень дельный материал подкинул, вроде все по кускам уже читал, но здесь по полочкам
Компьютеры — это как велосипед. Только для нашего сознания. Стив Джобс