1. VickWood 08.10.17 21:21 Сейчас в теме

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

Добрый день!
Помогите разобраться. Создала внешнюю обработку, которая должна будет создать трассировку. Однако при вызове метода 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 160 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 77 08.10.17 22:40 Сейчас в теме
(1) Видимо строка подключения некорректная. Покажите ее
4. VickWood 08.10.17 22:58 Сейчас в теме
(2)
		ADOСоединение.ConnectionString = "Provider=SQLOLEDB.1; Trusted_Connection=yes; Initial Catalog = srv001; Data Source=Lenovo-PC";
3. protexprotex 152 08.10.17 22:53 Сейчас в теме
(1)
ТекстЗапроса

Неправильный текст запроса - ТекстЗапроса = "exec sp_trace_create, 'C:\Projects'";
5. VickWood 08.10.17 22:59 Сейчас в теме
(3) А как правильно написать запрос? Может параметры не правильно задала?
6. protexprotex 152 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 152 08.10.17 23:59 Сейчас в теме
(5) И, если у Вас стоит exec - то это вызов какой - то хранимой процедуры?
10. VickWood 09.10.17 07:51 Сейчас в теме
(7) да, это хранимая процедура sql, которая создает трассировку.
11. protexprotex 152 09.10.17 09:05 Сейчас в теме
(10)
Я делаю так:


Результат = ADOConnection1.Execute('Set NoCount On Declare @ResultParam int Exec @ResultParam = ' + ProcName + ' Select @ResultParam As ResultParam');
9. slimper 160 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 - размерность в байтах.
NushaN; VickWood; +2 Ответить
13. VickWood 09.10.17 21:56 Сейчас в теме
(9)
полный список типов в документации по MS ADODB

А можете поделиться ссылочкой на документацию с полным описанием типов параметров ХП?
Перерыла гугл, ничего толкового не попадается(
15. slimper 160 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. 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 160 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. 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 160 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. 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 160 14.10.17 17:04 Сейчас в теме
(23)
Поправила, но ошибка все равно повторяется((

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

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

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

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

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

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

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

Вакансии

Удаленный консультант-разработчик 1С
Краснодар
зарплата от 60 000 руб. до 60 000 руб.
Полный день



Ведущий программист 1С
Москва
зарплата от 150 000 руб. до 180 000 руб.
Полный день

Руководитель проектов 1С
Москва
Полный день