Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

Как вернуть значение из Хранимой процедуры

Как вернуть значение из Хранимой процедуры
Я
   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
   youalex
 
2 - 08.12.20 - 20:47
просто select`ом из хранимки не вариант возвращать?
или прямо хочется с параметрами в ADO заморочиться?
   rudava
 
3 - 08.12.20 - 22:38
ну мне же сначала туда что то скормить нужно
а назад получить, вот как это в коде оформить
   youalex
 
4 - 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));    
КонецЕсли;
   youalex
 
5 - 09.12.20 - 09:44
+ можно еще извратиться, и выполнить пакетный (здесь по сути динамический) запрос через exec, примерно так:

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

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