Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Горячая тема (более 10 ответов) 1С7.7+1Cpp+OLEDB FoxPro+Хранимые процедуры (число прочтений - 4469 )
Burlak
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 65
Зарегистрирован: 28. Апреля 2008
1С7.7+1Cpp+OLEDB FoxPro+Хранимые процедуры
11. Декабря 2008 :: 12:05
Печать  
Хочу научиться работать с хранимыми процедурами.
Создал FoxPro DATABASE bis.dbc и поместил её в каталог 1С.
Из Fox-а - штатно,
DEBUG
SET PATH TO ('E:\1Tunes\BIS2008\') &&-- Sets path to database
OPEN DATABASE bis

  Справочник('ПРОДУКЦИЯ')
  RETURN 1

по шагам и RUN.

Пробую в 1С:

. . .
  Соединение="
    |Provider=VFPOLEDB.1;
//    |Deleted=Yes; 

    |Null = Yes;
    |Exclusive = No;
    |SourceType = DBF;
    |Data Source=" + КаталогИБ() + "bis.dbc;
    |Mode=Share Deny None;
//    |Mode=ReadWrite;

    |Extended Properties="""";
    |User ID="""";
    |Password="""";
    |Mask Password=False;
    |Collating Sequence=MACHINE;
    |DSN=""""";

  //-- Попытка открыть базу данных через OLEDB

  Попытка
    OLEDB=СоздатьОбъект("OLEDBData");
    Рез=OLEDB.Соединение(Соединение);
    cmdOLEDB=OLEDB.СоздатьКоманду();
    cmdOLEDB.Выполнить("SET ANSI OFF");
    mdw=CreateObject("MetaDataWork");
  Исключение
    Предупреждение("Неудачная попытка открыть базу данных через VFP OLFEDB");
  КонецПопытки;
. . .
cmdOLEDB.Выполнить("Справочник('ПРОДУКЦИЯ')");

Имею:
cmdOLEDB.Выполнить("Справочник('ПРОДУКЦИЯ')");

{Документ.СкладПеремещения.Форма.Модуль(477)}: FAILED! ICommandText::Execute(): Feature is not available.

Помогите разобраться.
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: 1С7.7+1Cpp+OLEDB FoxPro+Хранимые процедуры
Ответ #1 - 11. Декабря 2008 :: 12:14
Печать  
Не нужно создавать файл dbc.
Создаешь файл prg и туда пишешь хранимую процедуру
После этого можно обращаться к процедуре с параметрами.
Пример
http://www.1cpp.ru/forum/YaBB.pl?num=1209123521
и
Как получить время из поля TIME журнала (ДБФ)
http://www.1cpp.ru/forum/YaBB.pl?num=1180606447
  
Наверх
 
IP записан
 
Burlak
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 65
Зарегистрирован: 28. Апреля 2008
Re: 1С7.7+1Cpp+OLEDB FoxPro+Хранимые процедуры
Ответ #2 - 11. Декабря 2008 :: 13:48
Печать  
>kiruha. Ответ #1 - Сегодня :: 15:14
>Не нужно создавать файл dbc.
Вопрос спорный. В документации написано, что при открытии DATABESE хранимые процедуры переписываются на рабочую станцию. Но моя ошибка заключается в том, что в тексте ХП применяю запрещенные конструкции, в частности, макроподстановку. Отсюда и ошибка, т.е.

*!*    #DEFINE СПРАВОЧНИК [SC156]
  &&-- Построим id Элементов, входящих в узел "Продукция"
*!*    Select = " SELECT DISTINCT спр1.id as id"
*!*    From = " FROM "+СПРАВОЧНИК+" as спр1, "+СПРАВОЧНИК+" as спр2"
*!*    Where = " WHERE спр2.id=спр1.PARENTID AND спр1.ISMARK <> '*' AND спр2.ISFOLDER=1 AND UPPER(спр2.Descr) LIKE '"+UPPER(str_Узел)+"'"
*!*    ТекстЗапроса = Select+From+Where+" INTO CURSOR cur_Элементы" 
*!*    &ТекстЗапроса  &&-- Ошибка   
 
а так ок
  SELECT DISTINCT спр1.id as id;
   FROM SC156 as спр1, SC156 as спр2;
   WHERE спр2.id=спр1.PARENTID AND спр1.ISMARK <> '*' AND спр2.ISFOLDER=1 AND UPPER(спр2.Descr) LIKE 'ПРОДУКЦИЯ';
   INTO CURSOR cur_Элементы   
но это меня не устраивает
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: 1С7.7+1Cpp+OLEDB FoxPro+Хранимые процедуры
Ответ #3 - 11. Декабря 2008 :: 14:18
Печать  
Burlak писал(а) 11. Декабря 2008 :: 13:48:
>kiruha. Ответ #1 - Сегодня :: 15:14
>Не нужно создавать файл dbc.
Вопрос спорный. В документации написано, что при открытии DATABESE хранимые процедуры переписываются на рабочую станцию. Но моя ошибка заключается в том, что в тексте ХП применяю запрещенные конструкции, в частности, макроподстановку. Отсюда и ошибка, т.е.

*!*    #DEFINE СПРАВОЧНИК [SC156]
 &&-- Построим id Элементов, входящих в узел "Продукция"
*!*    Select = " SELECT DISTINCT спр1.id as id"
*!*    From = " FROM "+СПРАВОЧНИК+" as спр1, "+СПРАВОЧНИК+" as спр2"
*!*    Where = " WHERE спр2.id=спр1.PARENTID AND спр1.ISMARK <> '*' AND спр2.ISFOLDER=1 AND UPPER(спр2.Descr) LIKE '"+UPPER(str_Узел)+"'"
*!*    ТекстЗапроса = Select+From+Where+" INTO CURSOR cur_Элементы"  
*!*    &ТекстЗапроса  &&-- Ошибка    
 
а так ок
 SELECT DISTINCT спр1.id as id;
  FROM SC156 as спр1, SC156 as спр2;
  WHERE спр2.id=спр1.PARENTID AND спр1.ISMARK <> '*' AND спр2.ISFOLDER=1 AND UPPER(спр2.Descr) LIKE 'ПРОДУКЦИЯ';
  INTO CURSOR cur_Элементы    
но это меня не устраивает


1.Ну я использую хранимые без dbc и без проблем.
Приведенная обработка - работает.

2. В файл dbc нужно добавлять таблицы через Fox - у тебя "пустая база"

3.Макроподстановку применять не рекомендуется. Для этого есть скобки.
Пример
Код
Выбрать все
SELECT RECNO() FROM (NameFile) WHERE (KEYVALUE)=PustoySymbol 



4. Алгоритм не использует индекс, поэтому хуже стандартного УложитьСписокОбъектов,
так как в цикле происходит полное чтение таблицы на каждом шаге цикла
5.
Готовый работающий запрос для выборки (до 6 уровня, т.к. мне больше не надо, и не  оптимизированный по индексу
- было лень)
Код
Выбрать все
//
Функция севдоним)
	//КлючСловоОтбора IN или =
	СтрОтбораИД=" "+КлючСловоОтбора+" "+ВыбТоварыСтр;

	ТекстЗапроса = "";
	ТекстЗапроса =ТекстЗапроса+ "
	|
	|SELECT
	|	Спр1.ID  as Товар
	|FROM  $Справочник."+ВидСправочника+" as Спр1  
	|WHERE (Спр1.ISFOLDER=2) AND (Спр1.ID "+СтрОтбораИД+")
	|";

	Если Уровень>1 Тогда
		ТекстЗапроса =ТекстЗапроса+ "
		|UNION ALL
		|
		|SELECT
		|	Спр2_2.ID  
		|FROM $Справочник."+ВидСправочника+" as Спр2_2  
		|INNER JOIN $Справочник."+ВидСправочника+" as Спр1_2  ON (Спр2_2.ParentID = Спр1_2.ID) AND (Спр1_2.ISFOLDER=1) AND (Спр1_2.ID "+СтрОтбораИД+")
		|WHERE Спр2_2.ISFOLDER=2
		|";
	КонецЕсли;


	Если Уровень>2 Тогда
		ТекстЗапроса =ТекстЗапроса +"
		|UNION ALL
		|
		| SELECT
		|	Спр3.ID  
		|FROM $Справочник."+ВидСправочника+" as Спр3  
		|INNER JOIN $Справочник."+ВидСправочника+" as Спр2  ON (Спр3.ParentID = Спр2.ID) AND (Спр2.ISFOLDER=1)
		|INNER JOIN $Справочник."+ВидСправочника+" as Спр1  ON (Спр2.ParentID = Спр1.ID) AND (Спр1.ISFOLDER=1) AND (Спр1.ID "+СтрОтбораИД+")
		|WHERE Спр3.ISFOLDER=2
		|";
	КонецЕсли;

	Если Уровень>3 Тогда
		ТекстЗапроса =ТекстЗапроса +"
		|UNION ALL
		|
		| SELECT
		|	Спр4.ID  
		|FROM $Справочник."+ВидСправочника+" as Спр4
		|INNER JOIN $Справочник."+ВидСправочника+" as Спр3  ON (Спр4.ParentID = Спр3.ID) AND (Спр3.ISFOLDER=1)
		|INNER JOIN $Справочник."+ВидСправочника+" as Спр2  ON (Спр3.ParentID = Спр2.ID) AND (Спр2.ISFOLDER=1)
		|INNER JOIN $Справочник."+ВидСправочника+" as Спр1  ON (Спр2.ParentID = Спр1.ID) AND (Спр1.ISFOLDER=1) AND (Спр1.ID "+СтрОтбораИД+")
		|WHERE Спр4.ISFOLDER=2  
		|";
	КонецЕсли;

	Если Уровень>4 Тогда
		ТекстЗапроса =ТекстЗапроса +"
		|UNION ALL
		|
		|SELECT
		|	Спр5.ID  
		|FROM $Справочник."+ВидСправочника+" as Спр5  
		|INNER JOIN $Справочник."+ВидСправочника+" as Спр4  ON (Спр5.ParentID = Спр4.ID) AND (Спр4.ISFOLDER=1)
		|INNER JOIN $Справочник."+ВидСправочника+" as Спр3  ON (Спр4.ParentID = Спр3.ID) AND (Спр3.ISFOLDER=1)
		|INNER JOIN $Справочник."+ВидСправочника+" as Спр2  ON (Спр3.ParentID = Спр2.ID) AND (Спр2.ISFOLDER=1)
		|INNER JOIN $Справочник."+ВидСправочника+" as Спр1  ON (Спр2.ParentID = Спр1.ID) AND (Спр1.ISFOLDER=1) AND (Спр1.ID "+СтрОтбораИД+")
		|WHERE Спр5.ISFOLDER=2
		|";
	КонецЕсли;

	Если Уровень>5 Тогда
		ТекстЗапроса =ТекстЗапроса +"
		|UNION ALL
		|
		| SELECT
		|	Спр6.ID  
		|FROM $Справочник."+ВидСправочника+" as Спр6
		|INNER JOIN $Справочник."+ВидСправочника+" as Спр5  ON (Спр6.ParentID = Спр5.ID) AND (Спр5.ISFOLDER=1)
		|INNER JOIN $Справочник."+ВидСправочника+" as Спр4  ON (Спр5.ParentID = Спр4.ID) AND (Спр4.ISFOLDER=1)
		|INNER JOIN $Справочник."+ВидСправочника+" as Спр3  ON (Спр4.ParentID = Спр3.ID) AND (Спр3.ISFOLDER=1)
		|INNER JOIN $Справочник."+ВидСправочника+" as Спр2  ON (Спр3.ParentID = Спр2.ID) AND (Спр2.ISFOLDER=1)
		|INNER JOIN $Справочник."+ВидСправочника+" as Спр1  ON (Спр2.ParentID = Спр1.ID) AND (Спр1.ISFOLDER=1) AND (Спр1.ID "+СтрОтбораИД+")
		|WHERE Спр6.ISFOLDER=2
		|";
	КонецЕсли;
//	Сообщить(ТекстЗапроса);

	Возврат ТекстЗапроса;
КонецФункции 



6. Использовать хранимую - в принципе идея правильная, но только если будет задействован индекс
7. После компиляции в каталоге базы (на сервере) появляется файл ИмяПроцедуры.FXP
  
Наверх
 
IP записан
 
Burlak
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 65
Зарегистрирован: 28. Апреля 2008
Re: 1С7.7+1Cpp+OLEDB FoxPro+Хранимые процедуры
Ответ #4 - 11. Декабря 2008 :: 14:50
Печать  
>kiruha. Ответ #3 - Сегодня :: 17:18
Спасибо за помощь.
Это:

  LPARAMETERS СПРАВОЧНИК, str_Узел
 
  &&-- Построим все листья узла "str_Узел" справочника "СПРАВОЧНИК"
  &&----------------------------------------------------------------
  &&-- Удалим рабочие курсоры
  IF USED([cur_Листья])
    SELECT cur_Листья
    USE
  ENDIF
  IF USED([cur_Узлы])
    SELECT cur_Узлы
    USE
  ENDIF
  IF USED([cur_Элементы])
    SELECT cur_Элементы
    USE
  ENDIF

  &&-- Построим рабочие курсоры cur_Листья, cur_Элементы
  CREATE CURSOR cur_Листья (id C(9))

  SELECT DISTINCT спр1.id as id;
   FROM (СПРАВОЧНИК) as спр1, (СПРАВОЧНИК) as спр2;
   WHERE спр2.id=спр1.PARENTID AND спр1.ISMARK <> '*' AND спр2.ISFOLDER=1 AND UPPER(спр2.Descr) LIKE 'ПРОДУКЦИЯ';
   INTO CURSOR cur_Элементы   

  &&-- Цикл перебора вложенных узлов
  DO WHILE .T. Цикл
    &&-- Разберем элементы на узлы и листья
    &&--------------------------------------
    &&-- Выберем листья
    INSERT INTO cur_Листья(id) ;
     SELECT DISTINCT спр.id as id ;
     FROM (СПРАВОЧНИК) as спр, cur_Элементы as cur ;
     WHERE спр.id=cur.id AND спр.ISFOLDER=2
    &&-- Выберем узлы
    SELECT DISTINCT спр.id as id;
     FROM (СПРАВОЧНИК) as спр, cur_Элементы as cur;
     WHERE спр.id=cur.id AND спр.ISFOLDER=1;
     INTO CURSOR cur_Узлы   

    IF _Tally=0 Then
     EXIT &&-- Узлов больше нет
    ENDIF   
   
    &&-- Построим элементы
    SELECT cur_Элементы
    USE
    SELECT DISTINCT спр1.id as id;
     FROM (СПРАВОЧНИК) as спр1, (СПРАВОЧНИК) as спр2, cur_Узлы as cur ;
     WHERE спр2.id=cur.id AND спр2.id=спр1.PARENTID AND спр1.ISMARK <> '*' ;
     INTO CURSOR cur_Элементы   

    &&-- Удалим узлы
    SELECT cur_Узлы
    USE
  ENDDO 

  SELECT cur_Узлы
  USE
  SELECT cur_Элементы
  USE
 
  RETURN 1
 
... протащил и через ХП и .prg
Что лучше (ХП или .prg) пока не знаю. Относительно индексов Вы конечно правы. Но пока было не до них.
Относительно УложитьСписокОбъектов треба проверка.
  
Наверх
 
IP записан
 
Alex_Bob
Full Member
***
Отсутствует



Сообщений: 136
Местоположение: Липецк
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: 1С7.7+1Cpp+OLEDB FoxPro+Хранимые процедуры
Ответ #5 - 11. Декабря 2008 :: 15:57
Печать  
prg имеет смысл если не стоит полная версия Foxpro, а отлаживаться надо. Если FoxPro стоит, лучше dbc, так как туда можно кроме ХП засунуть еще и вьюхи и все будет в одном общем файле.
  

Необходимо время, чтобы восстановить хаос. (с) Дж. Буш (младший)
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: 1С7.7+1Cpp+OLEDB FoxPro+Хранимые процедуры
Ответ #6 - 11. Декабря 2008 :: 18:37
Печать  
Alex_Bob писал(а) 11. Декабря 2008 :: 15:57:
prg имеет смысл если не стоит полная версия Foxpro, а отлаживаться надо. Если FoxPro стоит, лучше dbc, так как туда можно кроме ХП засунуть еще и вьюхи и все будет в одном общем файле.


Представления (View)интересны только индексированные. 1С  к сожалению, обновляет только свои индексы (DD) в отличие от Fox.
Неиндексированным непонятно где можно применить - ничем не отличаются от подзапроса.
  
Наверх
 
IP записан
 
Chieftain
Senior Member
****
Отсутствует


___

Сообщений: 498
Местоположение: Тула
Зарегистрирован: 15. Февраля 2007
Пол: Мужской
Re: 1С7.7+1Cpp+OLEDB FoxPro+Хранимые процедуры
Ответ #7 - 11. Декабря 2008 :: 21:04
Печать  
Alex_Bob писал(а) 11. Декабря 2008 :: 15:57:
prg имеет смысл если не стоит полная версия Foxpro, а отлаживаться надо. Если FoxPro стоит, лучше dbc, так как туда можно кроме ХП засунуть еще и вьюхи и все будет в одном общем файле.

Лично меня в prg-файлах не устраивает именно то, что процедур бывает достаточно много, соответственно и файликов много. Когда-то была темка по плану выполнения, там с фоксом ковырялись малость. Вот эта идея мне чет очень понравилась, теперь с ХП так и работаю: http://www.1cpp.ru/forum/YaBB.pl?num=1210677779/15#28
  
Наверх
ICQ  
IP записан
 
Burlak
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 65
Зарегистрирован: 28. Апреля 2008
Re: 1С7.7+1Cpp+OLEDB FoxPro+Хранимые процедуры
Ответ #8 - 12. Декабря 2008 :: 04:54
Печать  
>kiruha. Ответ #3 - Вчера :: 17:18
>4. Алгоритм не использует индекс, поэтому хуже стандартного УложитьСписокОбъектов,
так как в цикле происходит полное чтение таблицы на каждом шаге цикла

Давайте проверим Ваше предположение.
Набросайте програмку пострения ИТ (ТЗ) с полями <id, descr> с информацией из справочника, начиная с некоторого узла. Для большей наглядности выполним рассматриваемые версии программы в цикле раз тысячу и сравним результаты.
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: 1С7.7+1Cpp+OLEDB FoxPro+Хранимые процедуры
Ответ #9 - 12. Декабря 2008 :: 08:44
Печать  
Burlak писал(а) 12. Декабря 2008 :: 04:54:
>kiruha. Ответ #3 - Вчера :: 17:18
>4. Алгоритм не использует индекс, поэтому хуже стандартного УложитьСписокОбъектов,
так как в цикле происходит полное чтение таблицы на каждом шаге цикла

Давайте проверим Ваше предположение.
Набросайте програмку пострения ИТ (ТЗ) с полями <id, descr> с информацией из справочника, начиная с некоторого узла. Для большей наглядности выполним рассматриваемые версии программы в цикле раз тысячу и сравним результаты.  


Здесь лежит обработка
Execute plan (ДБФ, FoxPro)
Можно вставлять любой запрос и FoxPro выдаст диагностические сообщения
использует ли он в данном запросе индексы и какие.
  
Наверх
 
IP записан
 
Burlak
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 65
Зарегистрирован: 28. Апреля 2008
Re: 1С7.7+1Cpp+OLEDB FoxPro+Хранимые процедуры
Ответ #10 - 12. Декабря 2008 :: 12:05
Печать  
>kiruha. Ответ #9 - Сегодня :: 11:44
Пока меня не интересует, что выдаст Fox. Предпочитаю прямые замеры. В данном случае временных интервалов. Как понимаю, есть два варианта получения всех "лисьев" на всех "узлах", подчиненных заданному, включая и его.  Меня интересует скорость выполнения в варианте с FoxPro .prg и варианте с УложитьСписокОбъектов. Я не большой специалист в 1С, поэтому и прошу дать программку с вариантом УложитьСписокОбъектов.
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать