Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Горячая тема (более 10 ответов) Работа с курсорами (число прочтений - 5232 )
jjjj1111
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 12
Зарегистрирован: 11. Мая 2012
Работа с курсорами
11. Мая 2012 :: 10:47
Печать  
Приветствую. А поделитесь опытом работы с куросорами в 1С++. А то вариант с пробежкой по курсору и выгрузкой итогового сета во временную таблицу у меня не проходит.
З.Ы. Тапком не бейте - в скуле не силен.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Работа с курсорами
Ответ #1 - 11. Мая 2012 :: 12:52
Печать  
зачем курсор
можно вполне и без курсора :

insert into #ИмяТаблицы(поля) select ...
  
Наверх
 
IP записан
 
jjjj1111
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 12
Зарегистрирован: 11. Мая 2012
Re: Работа с курсорами
Ответ #2 - 11. Мая 2012 :: 13:12
Печать  
Мне требуется в проводить вычисления в цикле.
Т.е. сложить значение предыдущей строки с текущей и вписать ее в таблицу.  Временная таблица ИМХО подходит не очень.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Работа с курсорами
Ответ #3 - 11. Мая 2012 :: 13:17
Печать  
jjjj1111 писал(а) 11. Мая 2012 :: 13:12:
Мне требуется в проводить вычисления в цикле.
Т.е. сложить значение предыдущей строки с текущей и вписать ее в таблицу.  Временная таблица ИМХО подходит не очень.

Про временную таблицу сам в (0) Написал.
Не знаю что там тебе нужно.
Напиши хранимую процедуру можешь с курсором которая и будет делать полностью твою задачу.
  
Наверх
 
IP записан
 
jjjj1111
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 12
Зарегистрирован: 11. Мая 2012
Re: Работа с курсорами
Ответ #4 - 11. Мая 2012 :: 13:34
Печать  
Z1 писал(а) 11. Мая 2012 :: 13:17:
Про временную таблицу сам в (0) Написал.
Не знаю что там тебе нужно.
Напиши хранимую процедуру можешь с курсором которая и будет делать полностью твою задачу.

Исправляюсь.
Мне требуется получить таблицу товаров с временем отсутствия этих товаров на складе.  
Как я делаю. Получаю таблицу товаров с остатками и оборотами отсортированную по полям товар,позиция документа. Прохожусь курсором по таблице. Результаты вычислений пишу во временную таблицу. Потом селектом получаю данные их временной таблицы.

Проблема - включаю отладку, копирую код из 1С в скульный запрос. В скуле результирующий набор нормальный, в 1С это одна строчка с первым товаром.

Вопрос - хотелось бы знать почему один и тот же запрос выдает разные результирующие наборы из 1С и SQL.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Работа с курсорами
Ответ #5 - 11. Мая 2012 :: 14:05
Печать  
скорее всего надо поставить в самом начале
set  nocount on
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Работа с курсорами
Ответ #6 - 12. Мая 2012 :: 02:48
Печать  
jjjj1111 писал(а) 11. Мая 2012 :: 10:47:
Приветствую. А поделитесь опытом работы с куросорами в 1С++. А то вариант с пробежкой по курсору и выгрузкой итогового сета во временную таблицу у меня не проходит.
З.Ы. Тапком не бейте - в скуле не силен.



А что именно не проходит?
Курсор не крутится, или посчитанный результат в таблицу не инсертится?

Как крутить курсор - смотри BOL, скажем, начиная с DECLARE CUSRSOR и далее по связным терминам (FETCH, CLOSE, DEALLOCATE) + смотри примеры, там все нормально расписано.
  
Наверх
 
IP записан
 
Salimbek
God Member
*****
Отсутствует



Сообщений: 862
Зарегистрирован: 06. Июня 2006
Пол: Мужской
Re: Работа с курсорами
Ответ #7 - 12. Мая 2012 :: 04:21
Печать  
Странно, если скуле не силен, то почему делаешь именно в нем? Выгрузи твои данные в ТЗ/ИТЗ, потом пробегаешься по ним и в результирующую ТЗ формируешь то, что тебе нужно.
  
Наверх
ICQ  
IP записан
 
jjjj1111
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 12
Зарегистрирован: 11. Мая 2012
Re: Работа с курсорами
Ответ #8 - 14. Мая 2012 :: 12:19
Печать  
Код
Выбрать все
РС.выполнить("Create table #TempTable (TovID char(9),X int)");


	ТекстЗапроса="

	|use torg
    |SET NOCOUNT ON
	|declare @tov char(9),@ost int,@osttek int,@poz int,@dvizh int, @X int
	|declare @tovp char(9),@pozp int
	|DECLARE curs CURSOR LOCAL FOR
	|SELECT Рсв.Товар,Рсв.Ост,Рсв.Позиция,Рсв.Движение FROM(
	|SELECT Р.Товар,Р.КвоОстаток as Ост,0 as Движение,0 as позиция FROM $РегистрОстатки.ОстаткиТоваров(:ДатаС,
	|		INNER JOIN $Справочник.Склады as Скл(NOLOCK) ON Скл.ID=Склад AND $Скл.НомерМагазина=:ВыбНМ
	|		INNER JOIN $Справочник.Товары as Тов(NOLOCK) ON Тов.ID=Товар
	|		INNER JOIN $Справочник.Сотрудники as Мен(NOLOCK) ON Мен.ID=$Тов.Менеджер AND $Мен.ведениетоваров=1,
	|	,(Товар,Склад),(Кво))as Р
	|
	|UNION ALL
	|
	|SELECT Р.Товар,0 as Ост,(Р.КвоПриход-Р.КвоРасход) as Движение,dbo._1s_timedoc_minus(Р.ПозицияДокумента,:ДатаС,:Старт,:Финиш) as позиция
	|FROM $РегистрОбороты.ОстаткиТоваров(:ДатаС,:ДатаПо~,Документ,
	|		INNER JOIN $Справочник.Склады as Скл(NOLOCK) ON Скл.ID=Склад AND $Скл.НомерМагазина=:ВыбНМ
	|		INNER JOIN $Справочник.Товары as Тов(NOLOCK) ON Тов.ID=Товар
	|		INNER JOIN $Справочник.Сотрудники as Мен(NOLOCK) ON Мен.ID=$Тов.Менеджер AND $Мен.ведениетоваров=1,
	|	,(Товар,Склад),(Кво))as Р)as Рсв
	|ORDER BY Рсв.Товар,Рсв.Позиция
	|

	|OPEN curs
	|Set @tovp='' set @pozp=0 set @x=0
	|FETCH NEXT FROM curs INTO @tov,@ost,@poz,@dvizh
	|WHILE @@FETCH_STATUS = 0
	|BEGIN
	|	IF @tov=@tovp
	|		BEGIN
	|	 		set @osttek=@osttek+@dvizh
	|			IF @osttekp<=0 set @X=@X+(@poz-@pozp)
	|			set @pozp=@poz
	|		END;
	|	ELSE
	|	 	BEGIN
	|			IF @osttekp<=0 set @X=:ОбщВремя-@pozp
	|			IF @X>0 BEGIN INSERT INTO #TempTable VALUES (@tovp,@X) set @X=0 END;
	|			IF @poz=0 set @X=:ОбщВремя
	|			set @osttek=@ost+@dvizh
	|			set @pozp=@poz
	|		END;
	|	set @tovp=@tov
	|	set @osttekp=@osttek
	|	FETCH NEXT FROM curs INTO @tov,@ost,@poz,@dvizh
	|END;
	|IF @X>0 INSERT INTO #TempTable VALUES (@tovp,@X)

	|Close curs
	|deallocate curs
	|
	|";

	РС.УстановитьТекстовыйПараметр("ВыбНМ",ВыбНМ);
	РС.УстановитьТекстовыйПараметр("ВыбМен",ВыбМен);
	РС.установитьтекстовыйпараметр("ПредМесяц",добавитьмесяц(НачМесяца(ДатаС),-1));
	РС.установитьтекстовыйпараметр("ТекМесяц",НачМесяца(ДатаС));
	РС.установитьтекстовыйпараметр("ДатаС",ДатаС);
	РС.установитьтекстовыйпараметр("ДатаПо",ДатаПо);
	РС.УстановитьТекстовыйПараметр("Старт",ВыбНМ.НачалоРаботы);
	РС.УстановитьТекстовыйПараметр("Финиш",ВыбНМ.КонецРаботы);
	*(датапо-датас+1));
	т=РС.выполнитьинструкцию(ТекстЗапроса);

	т=РС.выполнитьинструкцию("SELECT tovid as Тов,x FROM #TempTable");
	т.выбратьстроку();
	РС.выполнить("drop table #TempTable");  



Выполнение этой команды показывает сейчас таблицу из 3 строк.
Если копирую текст запроса в SSMS  то мне выводит нормальную таблицу из 10500 строк.
  
Наверх
 
IP записан
 
jjjj1111
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 12
Зарегистрирован: 11. Мая 2012
Re: Работа с курсорами
Ответ #9 - 14. Мая 2012 :: 12:21
Печать  
Salimbek писал(а) 12. Мая 2012 :: 04:21:
Странно, если скуле не силен, то почему делаешь именно в нем? Выгрузи твои данные в ТЗ/ИТЗ, потом пробегаешься по ним и в результирующую ТЗ формируешь то, что тебе нужно.

Скорость запроса. В ИТЗ соединения работают не так быстро как хотелось бы.
  
Наверх
 
IP записан
 
Вадимко
God Member
*****
Отсутствует


Нам бы чего про ОдноЦэ...

Сообщений: 1048
Местоположение: Минск
Зарегистрирован: 24. Мая 2006
Пол: Мужской
Re: Работа с курсорами
Ответ #10 - 17. Мая 2012 :: 21:46
Печать  
jjjj1111 писал(а) 14. Мая 2012 :: 12:21:
не так быстро как хотелось бы.


Курсоры также работают не так быстро как хотелось бы Улыбка
Ты напиши конкретнее что получить хочешь на пальцах, т.е. на простом примере
Можно сделать хитрое соединение
Посчитать, допустим, нарастающий итог или что-то еще
Может потребуется что-то предварительно упорядочить или присвоить "номер строки"... но все равно разница значительна
  

Кампутер, кофе и сигареты - это очень плохо для моего здоровья...
Наверх
IP записан
 
jjjj1111
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 12
Зарегистрирован: 11. Мая 2012
Re: Работа с курсорами
Ответ #11 - 23. Мая 2012 :: 06:31
Печать  
Вадимко писал(а) 17. Мая 2012 :: 21:46:
jjjj1111 писал(а) 14. Мая 2012 :: 12:21:
не так быстро как хотелось бы.

Курсоры также работают не так быстро как хотелось бы Улыбка
Ты напиши конкретнее что получить хочешь на пальцах, т.е. на простом примере

Требуется узнать какое количество времени товара не было на магазине.
Я беру остатки и движения товара в разрезе документов в периоде. Перевожу позицию документа во время. У меня получается временная ось с точками-движениями товара. После чего в курсоре я прохожу по оси и проверяю остаток товара.
  
Наверх
 
IP записан
 
jjjj1111
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 12
Зарегистрирован: 11. Мая 2012
Re: Работа с курсорами
Ответ #12 - 23. Мая 2012 :: 06:33
Печать  
Но вопрос даже не в этом. Меня заинтересовало почему одинаковые конструкции неодинаково работают в 1с и qa.

  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Работа с курсорами
Ответ #13 - 23. Мая 2012 :: 09:58
Печать  
jjjj1111 писал(а) 23. Мая 2012 :: 06:33:
Но вопрос даже не в этом. Меня заинтересовало почему одинаковые конструкции неодинаково работают в 1с и qa.


разные провайдыры
qa работает под OLE DB  1c под ODBC


для 1с разные запросы от того включене или выключен
РежимRPC(Знач);
  
Наверх
 
IP записан
 
jjjj1111
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 12
Зарегистрирован: 11. Мая 2012
Re: Работа с курсорами
Ответ #14 - 23. Мая 2012 :: 10:11
Печать  
Цитата:
разные провайдыры
qa работает под OLE DB  1c под ODBC

для 1с разные запросы от того включене или выключен
РежимRPC(Знач);

Ну провайдеры не объясняют ситуации...
Попробуйте если не сложно у себя выполнить запрос
Код
Выбрать все
	РС.выполнить("Create table #TempTable (TovID char(9),pr float)");

	ТекстЗапроса="
	|use torg
	|declare @tov char(9),@price float,@curs_rows bigint,@counter bigint
	|DECLARE curs CURSOR global static FOR
	|SELECT sc14.ID,sc14.sp153 from sc14
	|OPEN curs
	|set @curs_rows=@@cursor_rows
	|set @counter=0
	|WHILE @counter<@curs_rows
	|BEGIN
	|	set @counter=@counter+1
	|	FETCH absolute @counter FROM curs into @tov,@price
	|	INSERT INTO #TempTable VALUES (@tov,@price)
	|END;

	|Close curs
	|deallocate curs
	|";

	РС.выполнить(ТекстЗапроса);

	т=РС.выполнитьинструкцию("SELECT tovid,pr FROM #TempTable");
	т.выбратьстроку();
	сообщить(РС.выполнитьскалярный("SELECT count(*) FROM #TempTable"));
	РС.выполнить("drop table #TempTable");
 


где sc14 - таблица товаров с колвом строк 60000, sp153 цена.

  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать