Вызов хранимой процедуры из 1С

1. Vick Wood (VickWood) 08.10.17 21:21 Сейчас в теме
Добрый день!
Помогите разобраться. Создала внешнюю обработку, которая должна будет создать трассировку. Однако при вызове метода RecordSet.Open() вылетает ошибка:
{ВнешняяОбработка.СтатистикаЗапросовПоБД.Форма.Форма.Форма(48)}: Ошибка при вызове метода контекста (Open): Произошла исключительная ситуация (Microsoft OLE DB Provider for SQL Server): Неправильный синтаксис около конструкции ",".

Подскажите, в чем проблема?

Код:
	Попытка
		ADOСоединение  = Новый COMОбъект("ADODB.Connection");
		ADOСоединение.ConnectionString = СтрокаСостояния;
		ADOСоединение.Open();
   	Исключение
		Сообщить(ОписаниеОшибки());
	КонецПопытки; 
	
	Command = Новый COMObject("ADODB.Command");
	Command.ActiveConnection = ADOСоединение;
	Command.NamedParameters = Истина;
	ТекстЗапроса = "exec sp_trace_create, 'C:\Projects'";
	Command.CommandText = ТекстЗапроса; 
	Command.CommandType = 4; 
	
	RecordSet = Новый COMObject("ADODB.RecordSet");
	RecordSet.ActiveConnection = ADOСоединение;
  	RecordSet.CursorType = 3;
   	RecordSet.LockType = 2;
	
	Попытка
		RecordSet.Open(ТекстЗапроса, ADOСоединение);
		Таблица = Новый ТаблицаЗначений;
		КолКолонок = RecordSet.Fields.Count;
		Пока RecordSet.Eof()= 0 Цикл 
			Для Инд = 0 По КолКолонок - 1 Цикл 
				Таблица.ЗагрузитьКолонку(RecordSet.Fields(Инд).Value, RecordSet.Fields(Инд).Name);
			КонецЦикла;
			RecordSet.MoveNext();
		КонецЦикла;

	Исключение
		Сообщить(ОписаниеОшибки());
	КонецПопытки;
Показать
Найденные решения
20. slimper (slimper) 153 13.10.17 12:32 Сейчас в теме
(18) Если речь идет о sp_trace_create, то первый параметр у нее выходной

sp_trace_create [ @traceid = ] trace_id OUTPUT
, [ @options = ] option_value
, [ @tracefile = ] 'trace_file'
[ , [ @maxfilesize = ] max_file_size ]
[ , [ @stoptime = ] 'stop_time' ]
[ , [ @filecount = ] 'max_rollover_files'

т.e. вызов ХП в может выглядеть так:

file="С:\trace.trc"

com = New COMОбъект("ADODB.Command");
com.ActiveConnection=conn;
com.CommandText ="sp_trace_create";
com.CommandType=4;
com.Parameters.Append (com.CreateParameter("@TraceID", 3, 3,4));
com.Parameters.Append (com.CreateParameter("@options", 3, 1,4));
com.Parameters(1).value =6;
com.Parameters.Append (com.CreateParameter("@tracefile", 130, 1,245));
com.Parameters(2).value =file;
com.Prepared = true;
com.Execute();
//Возвращаем значение @TraceID
id=com.Parameters(0).value;
VickWood; +1 Ответить
Остальные ответы
2. Арман Б. (Dream_kz) 27 08.10.17 22:40 Сейчас в теме
(1) Видимо строка подключения некорректная. Покажите ее
4. Vick Wood (VickWood) 08.10.17 22:58 Сейчас в теме
(2)
		ADOСоединение.ConnectionString = "Provider=SQLOLEDB.1; Trusted_Connection=yes; Initial Catalog = srv001; Data Source=Lenovo-PC";
3. Сергей Смирнов (protexprotex) 146 08.10.17 22:53 Сейчас в теме
(1)
ТекстЗапроса

Неправильный текст запроса - ТекстЗапроса = "exec sp_trace_create, 'C:\Projects'";
5. Vick Wood (VickWood) 08.10.17 22:59 Сейчас в теме
(3) А как правильно написать запрос? Может параметры не правильно задала?
6. Сергей Смирнов (protexprotex) 146 08.10.17 23:56 Сейчас в теме
(5) Ну, типа такого:

ADOСоединение = Новый COMОбъект("ADODB.Connection");

    
    Попытка 
        ADOСоединение.Open("DRIVER=SQLite3 ODBC Driver;Database=C:\1C\PG\PR\PriceGrabber\db.dat;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;");
        
    Исключение
        Сообщить("ААААА!!!!!!");
    КонецПопытки;
    
    
    ДатаНачалаЗапроса = НачалоДня(ТекущаяДата());
    
    command = Новый COMОбъект("ADODB.Command");
    command.ActiveConnection = ADOСоединение;
    
    command.CommandText ="SELECT 
    | pg_list.ID AS КодПрайса,
    | pg_list.PVID AS PVID,
    | datetime(pg_list.PRICEDTE + julianday(""1899-12-30"")) as Дата,
    | pg_list.DESCR as ИмяПостовщика
    |FROM 
    | pg_list
    |WHERE
    | datetime(pg_list.PRICEDTE + julianday(""1899-12-30"")) >= datetime(julianday(""" + Формат(ДатаНачалаЗапроса,"ДФ='yyyy-MM-dd HH:mm:ss'") + """))";
    
    
    Попытка
        результат = command.Execute();
    Исключение
        
        Сообщить("ООООООО!!!!!!!!!!!!");
        
    КонецПопытки;
    
    
    Вр = 1;
   // Перебор данных
 
    Если НЕ результат.EOF() Тогда
        результат.MoveFirst();                 
        Пока результат.EOF() = 0 Цикл
            
            Сообщить(Вр);
            результат.MoveNext();
            Вр = Вр + 1;
        КонецЦикла;
    КонецЕсли;
Показать

:-)))
7. Сергей Смирнов (protexprotex) 146 08.10.17 23:59 Сейчас в теме
(5) И, если у Вас стоит exec - то это вызов какой - то хранимой процедуры?
10. Vick Wood (VickWood) 09.10.17 07:51 Сейчас в теме
(7) да, это хранимая процедура sql, которая создает трассировку.
11. Сергей Смирнов (protexprotex) 146 09.10.17 09:05 Сейчас в теме
(10)
Я делаю так:


Результат = ADOConnection1.Execute('Set NoCount On Declare @ResultParam int Exec @ResultParam = ' + ProcName + ' Select @ResultParam As ResultParam');
9. slimper (slimper) 153 09.10.17 05:54 Сейчас в теме
(1) Пример вызова хранимой процедуры, возвращающей набор данных

Function Example(god,dtk) 
		
com = New COMОбъект("ADODB.Command");
Try
  com.ActiveConnection=ADOСоединение;
   com.CommandText ="sp_storedproc";
   com.CommandType=4;
   com.Parameters.Append (com.CreateParameter("@igod", 3, 1,4));
   com.Parameters(0).value = god;
   com.Parameters.Append(com.CreateParameter("@rdtn", 135, 1,8));
   com.Parameters(1).value = dtk;
   com.Prepared = true;
   RS=com.Execute();
   return RS;
Except
   return undefined;
EndTry;	
EndFunction
Показать

Параметры функции CreateParameter:

Function CreateParameter([Name As String], [Type As DataTypeEnum = adEmpty], [Direction As ParameterDirectionEnum = adParamInput], [Size As ADO_LONGPTR], [Value]) As Parameter

Name - имя параметра хранимой процедуры
Type - тип параметра ( 3 - целое, 135 - дата, полный список типов в документации по MS ADODB)
Direction - направление передачи параметров 1 - входной, 3 - выходной
Size - размерность в байтах.
VickWood; +1 Ответить
13. Vick Wood (VickWood) 09.10.17 21:56 Сейчас в теме
(9)
полный список типов в документации по MS ADODB

А можете поделиться ссылочкой на документацию с полным описанием типов параметров ХП?
Перерыла гугл, ничего толкового не попадается(
15. slimper (slimper) 153 10.10.17 06:22 Сейчас в теме
(13) Два варианта: "теоретический" и "практический".

1. https://docs.microsoft.com/ru-ru/sql/ado/reference/ado-api/ado-code-examples
2. Открываете книгу Excel, переходите в редактор VB (Alt+F11). Затем меню Tools -> References устанавливаете ссылку на Мicrosoft ActiveX Data Objects 2.8 Library.
Далее вызываете Оbject Browser (меню View -> Оbject Browser или F2). В списке "Project / Library выбираете ADODB.
VickWood; +1 Ответить
18. Vick Wood (VickWood) 12.10.17 23:54 Сейчас в теме
(9) Добавила параметры по примеру:
	Command.Parameters.Append(Command.CreateParameter("@options", 3, 1, 4));
		Command.Parameters(0).value = 6;		

Но, вылетает ошибка:
{ВнешняяОбработка.СтатистикаЗапросовПоБД.Форма.Форма.Форма(36)}: Ошибка при вызове метода контекста (Execute): Произошла исключительная ситуация (Microsoft OLE DB Provider for SQL Server): Процедура ожидает параметр "@options" типа "int".

Что может быть не так? Перепробовала разные типы для целых чисел, ошибка одна и та же каждый раз вылетает...((
20. slimper (slimper) 153 13.10.17 12:32 Сейчас в теме
(18) Если речь идет о sp_trace_create, то первый параметр у нее выходной

sp_trace_create [ @traceid = ] trace_id OUTPUT
, [ @options = ] option_value
, [ @tracefile = ] 'trace_file'
[ , [ @maxfilesize = ] max_file_size ]
[ , [ @stoptime = ] 'stop_time' ]
[ , [ @filecount = ] 'max_rollover_files'

т.e. вызов ХП в может выглядеть так:

file="С:\trace.trc"

com = New COMОбъект("ADODB.Command");
com.ActiveConnection=conn;
com.CommandText ="sp_trace_create";
com.CommandType=4;
com.Parameters.Append (com.CreateParameter("@TraceID", 3, 3,4));
com.Parameters.Append (com.CreateParameter("@options", 3, 1,4));
com.Parameters(1).value =6;
com.Parameters.Append (com.CreateParameter("@tracefile", 130, 1,245));
com.Parameters(2).value =file;
com.Prepared = true;
com.Execute();
//Возвращаем значение @TraceID
id=com.Parameters(0).value;
VickWood; +1 Ответить
21. Vick Wood (VickWood) 13.10.17 22:30 Сейчас в теме
(20) Спасибо большое! Все получилось)
Однако, еще одна загвоздка: мне необходимо следом вызвать еще одну ХП sp_trace_setevent, но вылетает ошибка, что для данной процедуры слишком много аргументов, хотя в описании к этой ХП они все указаны. Подскажите, пжл, в чем может быть проблема? И как лучше задать значения параметров, если значений должно быть несколько (например, для параметра 1 и 2)?
	Попытка
		Command.ActiveConnection = ADOСоединение;
		Command.CommandText = "sp_trace_setevent";
		Command.CommandType = 4;
		Command.Parameters.Append(Command.CreateParameter("@TraceID", 3, 1, 4));
		Command.Parameters(0).Value = id;
		Command.Parameters.Append(Command.CreateParameter("@eventid", 3, 1, 255));
		Command.Parameters(1).Value = 10;
		Command.Parameters.Append(Command.CreateParameter("@columnid", 3, 1, 255));
		Command.Parameters(2).Value = 1;
		Command.Parameters.Append(Command.CreateParameter("@on", 11, 1, 1));
		Command.Parameters(3).Value = 1;
		Command.Prepared = Истина; 
		Command.Execute();
	Исключение
		Сообщить(ОписаниеОшибки());
	КонецПопытки;
Показать
22. slimper (slimper) 153 14.10.17 07:40 Сейчас в теме
(21)
но вылетает ошибка

Parameters of all SQL Trace stored procedures (sp_trace_xx) are strictly typed. If these parameters are not called with the correct input parameter data types, as specified in the argument description, the stored procedure will return an error.
Параметры 1 и 2 имеют тип int и должны задаваться со значениями (3,1,4).

И как лучше задать значения параметров, если значений должно быть несколько (например, для параметра 1 и 2)?

Users must execute sp_trace_setevent for each column added for each event. During each execution, if @on is set to 1, sp_trace_setevent adds the specified event to the list of events of the trace. If @on is set to 0, sp_trace_setevent removes the specified event from the list.
23. Vick Wood (VickWood) 14.10.17 14:23 Сейчас в теме
(22)
Параметры 1 и 2 имеют тип int и должны задаваться со значениями (3,1,4).

Поправила, но ошибка все равно повторяется((
Может параметр @TraceID не надо указывать?

(22)
Users must execute sp_trace_setevent for each column added for each event. During each execution, if @on is set to 1, sp_trace_setevent adds the specified event to the list of events of the trace. If @on is set to 0, sp_trace_setevent removes the specified event from the list.

Т.е. получается необходимо вызывать эту процедуру, каждый раз добавляя в значение параметра по событию и столбцу к этому событию?
типа так:
	Попытка
		Command.ActiveConnection = ADOСоединение;
		Command.CommandText = "sp_trace_setevent";
		Command.CommandType = 4;
		Command.Parameters.Append(Command.CreateParameter("@TraceID", 3, 1, 4));
		Command.Parameters(0).Value = ID;
		Command.Parameters.Append(Command.CreateParameter("@eventid", 3, 1, 4));
		Command.Parameters(1).Value = 10;
		Command.Parameters.Append(Command.CreateParameter("@columnid", 3, 1, 4));
		Command.Parameters(2).Value = 13;
		Command.Parameters.Append(Command.CreateParameter("@on", 11, 1, 1));
		Command.Parameters(3).Value = 1;
		Command.Prepared = Истина; 
		Command.Execute();
	Исключение
		Сообщить(ОписаниеОшибки());
	КонецПопытки;
Показать
24. slimper (slimper) 153 14.10.17 17:04 Сейчас в теме
(23)
Поправила, но ошибка все равно повторяется((

Мне не удалось получить эту ошибку. На sql 2005 и 2008 процедура отрабатывает без ошибок. @TraceID - дескриптор сеанса трассировки и он нужен для sp_trace_setevent.

Т.е. получается необходимо вызывать эту процедуру, каждый раз добавляя в значение параметра по событию и столбцу к этому событию?

Да.
25. Vick Wood (VickWood) 14.10.17 18:04 Сейчас в теме
(24)
Мне не удалось получить эту ошибку. На sql 2005 и 2008 процедура отрабатывает без ошибок. @TraceID - дескриптор сеанса трассировки и он нужен для sp_trace_setevent.

А чему параметр @TraceID долен быть равен? Значению, которое мы получили вот тут:
(20)
id=com.Parameters(0).value;

Может быть я не правильно значение этому параметру задала?
26. slimper (slimper) 153 14.10.17 18:20 Сейчас в теме
(25) XП sp_trace_create создает экземпляр трассировки и возвращает указатель на этот экземпляр (@TraceID). Этот указатель должен быть передан в XП sp_trace_setevent, для того, чтобы она "знала" с какой трассировкой она работает.

Пример:

DECLARE @RC int, @TraceID int, @on BIT
EXEC @rc = sp_trace_create @TraceID output, 0, N'C:\SampleTrace'

-- Select the return code to see if the trace creation was successful.
SELECT RC = @RC, TraceID = @TraceID

-- Set the events and data columns you need to capture.
SELECT @on = 1

-- 10 is RPC:Completed event. 1 is TextData column.
EXEC sp_trace_setevent @TraceID, 10, 1, @on
27. slimper (slimper) 153 14.10.17 20:05 Сейчас в теме
(25) Попробуйте следующий вариант:

1. Создайте свою ХП обертку в MS-Sql:


CRE ATE procedure [dbo].[myTrace]

@pFile nvarchar(245)=null
as
--
DECLARE @RC int, @TraceID int, @on BIT
EXEC @rc = sp_trace_create @TraceID output, 6, @pFile

-- Select the return code to see if the trace creation was successful.
SELECT RC = @RC, TraceID = @TraceID

-- Set the events and data columns you need to capture.
SELECT @on = 1

-- 10 is RPC:Completed event. 1 is TextData column.
EXEC sp_trace_setevent @TraceID, 10, 1, @on
-- 13 is SQL:BatchStarting, 11 is LoginName
EXEC sp_trace_setevent @TraceID, 13, 11, @on
-- 13 is SQL:BatchStarting, 14 is StartTime
EXEC sp_trace_setevent @TraceID, 13, 14, @on
-- 12 is SQL:BatchCompleted, 15 is EndTime
EXEC sp_trace_setevent @TraceID, 12, 15, @on
-- 13 is SQL:BatchStarting, 1 is TextData
EXEC sp_trace_setevent @TraceID, 13, 1, @on


-- Start Trace (status 1 = start)
EXEC @RC = sp_trace_setstatus @TraceID, 1

Показать


2. В 1С сделайте вызов данной ХП:

file="C:\test";
len=strlen(file);

com = New COMОбъект("ADODB.Command");
com.ActiveConnection = con;
com.CommandText = "myTrace";
com.CommandType = 4;
com.Parameters.Append (com.CreateParameter("@pFile", 130, 1,len));
com.Parameters(0).value =file;
com.Prepared = Истина;
com.Execute();
14. Oleg Space (spacecraft) 09.10.17 22:36 Сейчас в теме
(1)
Попытка
	ADOСоединение  = Новый COMОбъект("ADODB.Connection");
	ADOСоединение.ConnectionString = СтрокаСостояния;
	ADOСоединение.Open();

	Command = Новый COMObject("ADODB.Command");
	Command.ActiveConnection = ADOСоединение;
	ТекстЗапроса = "exec sp_trace_create 'C:\Projects'";
	Command.CommandText = ТекстЗапроса; 
	Command.CommandType = 4; 

	RecordSet = Command.Execute();

	Таблица = Новый ТаблицаЗначений;
	КолКолонок = RecordSet.Fields.Count;
	Пока RecordSet.Eof()= 0 Цикл 
	    Для Инд = 0 По КолКолонок - 1 Цикл 
	        Таблица.ЗагрузитьКолонку(RecordSet.Fields(Инд).Value, RecordSet.Fields(Инд).Name);
	    КонецЦикла;
	    RecordSet.MoveNext();
	КонецЦикла;

Исключение
    Сообщить(ОписаниеОшибки());
КонецПопытки;
Показать
8. Николай Пугачев (nickpugachev) 09.10.17 01:45 Сейчас в теме
У вас CommandType установлен в 4 - вызов хранимой процедуры. Зачем тогда exec?
Перед первым параметром запятая не нужна

То есть должно быть примерно вот так
ТекстЗапроса = "sp_trace_create 'C:\Projects'";


Можно еще передавать каталог как параметр
12. Vick Wood (VickWood) 09.10.17 21:09 Сейчас в теме
(8) нет, не вышло, вылетает теперь ошибка:
{ВнешняяОбработка.СтатистикаЗапросовПоБД.Форма.Форма.Форма(48)}: Ошибка при вызове метода контекста (Open): Произошла исключительная ситуация (Microsoft OLE DB Provider for SQL Server): Выполнение запроса процедура "sp_trace_create" окончилось неудачно, так как "sp_trace_create" является объектом процедура.
16. Сергей Долинин (ImHunter) 15 10.10.17 11:14 Сейчас в теме
Достаточно активно работаю с ХП. И написал для этого определенное количество строк кода. В итоге, моя работа сводится к инициализации параметров. Типа так:
ПарамХП = МодульБД.ИнициализироватьХП(ИмяПроцедурыСохраненияСообщения(), Соединение);

И выполнению ХП. Типа так:
МодульБД.ВыполнитьХранимуюПроцедуру(ПарамХП, Соединение, 
		Новый Структура("XML, profile_id", Текстовка, Перечисления.НазначенияПочтовыхПрофилей.ПолучитьИдентификатор(НазначениеПрофиля)),
		ДопПараметры
	);

Инициализирую отдельно для того, чтобы закэшировать созданные объекты параметров и команды ХП. Просто если одну процедуру много раз выполнить в каком-то цикле (и каждый раз ее создавать), то по замерам времени видим, что очень большие затраты происходят именно на создании процедуры параметров. При несложных ХП, эти затраты превышают время выполнения самой ХП.
Хотел выложить публикацией код. Но нужно код из общего модуля повыдергивать и вставить, например, во внешку. На это нет времени.
В неприбранном виде могу и сюда запостить.
17. Vick Wood (VickWood) 12.10.17 22:34 Сейчас в теме
(16) Я так понимаю, функции, представленные выше, вы сами писали?
Учитывая то, что я только начинаю знакомиться с ХП, то в такие тонкости мне вникать еще рано)
Сейчас моя задача, правильно передать параметры в процедуру sp_trace_create, в том коде, который я уже написала. Судя по всему, ошибка вылетает именно из-за неправильных параметров...
Если сможете помочь разобраться с передачей параметров в ХП sp_trace_create, буду признательна)
19. Сергей Долинин (ImHunter) 15 13.10.17 06:41 Сейчас в теме
(17) В вашем примере вы же исполняете запрос (вместе с exec и параметрами). И тогда должно сработать Command.CommandType = 1. Попробуйте сначала так.
Оставьте свое сообщение