Переключение на Главную Страницу Страницы: [1]  ОтправитьПечать
Горячая тема (более 10 ответов) Работа с курсорами (число прочтений - 5717 )
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 записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Работа с курсорами
Ответ #15 - 23. Мая 2012 :: 10:53
Печать  
(14) что выполнить
если у меня в справочнике нет sc14

и почему при добавлению в таблицу помещаешь туда и папки и элементы ?

метод выполнить() считается устаревшим и в новых программах его использовать не рекомендуется
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Работа с курсорами
Ответ #16 - 23. Мая 2012 :: 11:04
Печать  
(15) и зачем нужен 15
если именно этот случай то елементарно все без курсора делается
однм insert

  
Наверх
 
IP записан
 
jjjj1111
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 12
Зарегистрирован: 11. Мая 2012
Re: Работа с курсорами
Ответ #17 - 23. Мая 2012 :: 11:42
Печать  
Z1 писал(а) 23. Мая 2012 :: 10:53:
(14) что выполнить
если у меня в справочнике нет sc14

А найти достаточно большой справочник нельзя?
  
Наверх
 
IP записан
 
jjjj1111
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 12
Зарегистрирован: 11. Мая 2012
Re: Работа с курсорами
Ответ #18 - 23. Мая 2012 :: 11:44
Печать  
Z1 писал(а) 23. Мая 2012 :: 11:04:
если именно этот случай то елементарно все без курсора делается
однм insert

Нет - это не тот случай, это тест. Ту задачу с которой я начинал я описал в 11 посте.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Работа с курсорами
Ответ #19 - 23. Мая 2012 :: 12:12
Печать  
jjjj1111 писал(а) 23. Мая 2012 :: 11:44:
Z1 писал(а) 23. Мая 2012 :: 11:04:
если именно этот случай то елементарно все без курсора делается
однм insert

Нет - это не тот случай, это тест. Ту задачу с которой я начинал я описал в 11 посте.

Так ответ уже давно дан.
Внимательно прочти пост 3(там ответ) и если сделаешь
как там написано то отличий не будет.
  
Наверх
 
IP записан
 
jjjj1111
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 12
Зарегистрирован: 11. Мая 2012
Re: Работа с курсорами
Ответ #20 - 23. Мая 2012 :: 12:18
Печать  
Цитата:
Так ответ уже давно дан.
Внимательно прочти пост 3(там ответ) и если сделаешь
как там написано то отличий не будет.

Именно так и решил. Однако интересует вопрос почему так обрезаются итоги. QA-60000 строк, 1С++-150-180 строк. Боюсь что причина может вылезти где нибудь еще.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Работа с курсорами
Ответ #21 - 23. Мая 2012 :: 12:32
Печать  
jjjj1111 писал(а) 23. Мая 2012 :: 12:18:
Цитата:
Так ответ уже давно дан.
Внимательно прочти пост 3(там ответ) и если сделаешь
как там написано то отличий не будет.

Именно так и решил. Однако интересует вопрос почему так обрезаются итоги. QA-60000 строк, 1С++-150-180 строк. Боюсь что причина может вылезти где нибудь еще.

скорее всего разная область видимости(declare) переменных - времени жизни

  
Наверх
 
IP записан
 
jjjj1111
YaBB Newbies
*
Отсутствует


1C++ rocks!

Сообщений: 12
Зарегистрирован: 11. Мая 2012
Re: Работа с курсорами
Ответ #22 - 23. Мая 2012 :: 12:54
Печать  
Цитата:
скорее всего разная область видимости(declare) переменных - времени жизни

Мне кажется, что это страничный обмен и/или ограничение выполнитьинструкцию на мультистейтмент. В любом случае хотелось бы узнать от гуру. Посему и пришел сюда.
  
Наверх
 
IP записан
 
Satans Claws
God Member
*****
Отсутствует


1C++ rocks!

Сообщений: 721
Зарегистрирован: 29. Ноября 2010
Re: Работа с курсорами
Ответ #23 - 24. Мая 2012 :: 02:53
Печать  
jjjj1111 писал(а) 23. Мая 2012 :: 10:11:
Код
Выбрать все
	РС.выполнить("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");
 




Не совсем въезжаю, как ты курсором бегаешь...
Все разы, когда приходилось юзать, писал примерно так:

Код
Выбрать все
OPEN curs

FETCH NEXT FROM curs
INTO @tov,@price

WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO #TempTable VALUES (@tov,@price)

FETCH NEXT FROM curs
INTO @tov,@price
END
 



Хотя, тут возможен вариант "меня так научили"...
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 
ОтправитьПечать