![]() |
|
v7: Пишу прямой запрос - получается кривой. Выпрямим? | ☑ | ||
---|---|---|---|---|
0
Андрей_Андреич
naïve
26.09.12
✎
08:21
|
Пытаюсь сделать Update таблицы. При этом рекурсивно к этой же таблице обращаюсь. Не получается. Если сделать копию таблицы и обращаться к ней - все ОК. Помогите разобраться - оно невозможно в принципе или я истинный 1Сник (тупой и ленивый)?
|
|||
1
Андрей_Андреич
naïve
26.09.12
✎
08:23
|
Собственно текст запроса
|Update "+ТаблицаГрупп+" |Set |Сортировка = Rtrim(ДопТаблица.Сортировка)+RTrim(ТаблицаГрупп.Сортировка) |From "+ТаблицаГрупп+" ТаблицаГрупп |Left Join "+ТаблицаГрупп+" ДопТаблица (NoLock) On ТаблицаГрупп.ParentId = ДопТаблица.Id |Where ТаблицаГрупп.Уровень=0 |
|||
2
vde69
26.09.12
✎
08:26
|
небось рекурсия в транзакции???
|
|||
3
Андрей_Андреич
naïve
26.09.12
✎
08:29
|
(2) Да уже рекурсию выбросил - без всяких циклов не разу не выполняется. Тупой отчет. Не понравилось как иерархия групп обрабатывается - решил переписать. Ну и встрял там же, где сто лет назад.
|
|||
4
Андрей_Андреич
naïve
26.09.12
✎
08:30
|
Если сделать копию таблицы - выполняется
|Select ID, ParentId, Сортировка Into "+ДопТаблица+" From "+ТаблицаГрупп+" Where Уровень = @MaxLevel |Update "+ТаблицаГрупп+" |Set |Сортировка = Rtrim(ДопТаблица.Сортировка)+RTrim(ТаблицаГрупп.Сортировка) |From "+ТаблицаГрупп+" ТаблицаГрупп |Left Join "+ДопТаблица+" ДопТаблица (NoLock) On ТаблицаГрупп.ParentId = ДопТаблица.Id |Where ТаблицаГрупп.Уровень=0 |
|||
5
trad
26.09.12
✎
08:50
|
что бы запрос из (1) алгоритмически соответствовал запросу из (4) он должен быть таким:
|Update "+ТаблицаГрупп+" |Set |Сортировка = Rtrim(ДопТаблица.Сортировка)+RTrim(ТаблицаГрупп.Сортировка) |From "+ТаблицаГрупп+" ТаблицаГрупп |Left Join "+ТаблицаГрупп+" ДопТаблица (NoLock) On ТаблицаГрупп.ParentId = ДопТаблица.Id And ДопТаблица.Уровень = @MaxLevel |Where ТаблицаГрупп.Уровень=0 |
|||
6
Андрей_Андреич
naïve
26.09.12
✎
08:55
|
(5) сейчас попробую - вариантов кучу перебрал естественно. может такого и не было
|
|||
7
Андрей_Андреич
naïve
26.09.12
✎
08:57
|
(5) вигвам
|
|||
8
Андрей_Андреич
naïve
26.09.12
✎
09:00
|
(5) то бишь не работает
|
|||
9
vde69
26.09.12
✎
09:01
|
(3) ты не рекурсия а транзакцию выкини.
проблемма в уровне изоляции разрешающем грязное чтение в транзакции... |
|||
10
Андрей_Андреич
naïve
26.09.12
✎
09:06
|
(9) Тупой, вашбродь. Где транзвкция которую выкинуть?
|
|||
11
vde69
26.09.12
✎
09:09
|
(10) покажи полный код и от куда вызываешь (обработка, документ...)
|
|||
12
Андрей_Андреич
naïve
26.09.12
✎
09:11
|
(11) Куча мусора - приведу в порядок и выложу. А на словах принцип нельзя?
|
|||
13
Андрей_Андреич
naïve
26.09.12
✎
09:14
|
Функция глСортировкаПоИерархии2(ИмяТаблицы,НаименованиеПоля,НаименованиеСправочника,СуммируемыеПоля="") Экспорт
Перем ТекстЗапроса, ТаблицаГрупп, ДопТаблица; ДопТаблица="[##"+глПолучитьGUID()+"]"; ТаблицаГрупп="[##"+глПолучитьGUID()+"]"; ТекстЗапроса="Set NoCount OFF |Declare @MaxLevel Integer |Select Номенклатура.Id, Номенклатура.ParentId |, Cast(0 As Integer) Уровень |, Sum(ИмяТаблицы.Себестоимость) Себестоимость |, Sum(ИмяТаблицы.Количество) Количество |, Sum(ИмяТаблицы.ПроданоНаСумму) ПроданоНаСумму |Into "+ТаблицаГрупп+" |From "+ИмяТаблицы+" ИмяТаблицы (NoLock) |Left Join $Справочник.Номенклатура Номенклатура (NoLock) On ИмяТаблицы.Товар_ParentId=Номенклатура.Id |Group By Номенклатура.ID, Номенклатура.ParentId |Set @MaxLevel=1 | |While 1=1 Begin |Insert Into "+ТаблицаГрупп+" |Select Номенклатура.Id, Номенклатура.ParentId |, Cast(@MaxLevel As Integer) Уровень |, Sum(ТаблицаГрупп.Себестоимость) Себестоимость |, Sum(ТаблицаГрупп.Количество) Количество |, Sum(ТаблицаГрупп.ПроданоНаСумму) ПроданоНаСумму |From "+ТаблицаГрупп+" ТаблицаГрупп (NoLock) |Inner Join $Справочник.Номенклатура Номенклатура (NoLock) On ТаблицаГрупп.ParentId=Номенклатура.Id |Where Уровень=@MaxLevel-1 |Group By Номенклатура.ID, Номенклатура.ParentId | | If @@RowCount=0 Begin | Break | END | Set @MaxLevel=@MaxLevel+1 |END | |Alter Table "+ТаблицаГрупп+" |Add Сортировка Char(500), Code Char(7) |Update "+ТаблицаГрупп+" |Set |Уровень = 0 |,Сортировка = Номенклатура.Descr, Code = Номенклатура.Code |From "+ТаблицаГрупп+" ТаблицаГрупп (NoLock) |Left Join $Справочник.Номенклатура Номенклатура On ТаблицаГрупп.Id = Номенклатура.Id |Update "+ТаблицаГрупп+" |Set Уровень=1 |, Сортировка=LTrim(Str(1))+RTrim(Сортировка) |From "+ТаблицаГрупп+" Where ParentId = ' 0 ' | |Set @MaxLevel=1 | |While 1=1 Begin //|Select ID, ParentId, Сортировка Into "+ДопТаблица+" From "+ТаблицаГрупп+" Where Уровень = @MaxLevel |Update "+ТаблицаГрупп+" |Set |Сортировка = Rtrim(ДопТаблица.Сортировка)+RTrim(ТаблицаГрупп.Сортировка) |From "+ТаблицаГрупп+" ТаблицаГрупп |Left Join "+ТаблицаГрупп+" ДопТаблица (NoLock) On ТаблицаГрупп.ParentId = ДопТаблица.Id And ДопТаблица.Уровень = @MaxLevel |Where ТаблицаГрупп.Уровень=0 //|Where ДопТаблица.Уровень = @MaxLevel //| If @@RowCount=0 Begin | Break //| END | Set @MaxLevel=@MaxLevel+1 |END | |"; ТЗ=СоздатьОбъект("ТаблицаЗначений"); Попытка РадугаЗапрос.ВыполнитьИнструкцию(ТекстЗапроса,ТЗ); Исключение Предупреждение("Произошла ошибка при выполнении запроса (Создание таблицы )!!!"); Текст=СоздатьОбъект("Текст"); Текст.ДобавитьСтроку(ТекстЗапроса); Текст.Показать("11"); Сообщить(ОписаниеОшибки()); Возврат ""; КонецПопытки; ТекстЗапроса=" |Select Id [Товар $Справочник.Номенклатура] , ParentId [Группа $Справочник.Номенклатура] |, ParentId ParentId, Id Id, Уровень, Сортировка Наименование, Code Код |, Себестоимость Себестоимость |, Количество Количество |, ПроданоНаСумму ПроданоНаСумму //|Into "+ТаблицаГрупп+" |From "+ТаблицаГрупп+" ИмяТаблицы (NoLock) |"; ТЗ=СоздатьОбъект("ТаблицаЗначений"); Попытка РадугаЗапрос.ВыполнитьИнструкцию(ТекстЗапроса,ТЗ); Исключение Предупреждение("Произошла ошибка при выполнении запроса (Создание таблицы )!!!"); Текст=СоздатьОбъект("Текст"); Текст.ДобавитьСтроку(ТекстЗапроса); Текст.Показать("12"); Сообщить(ОписаниеОшибки()); Возврат ""; КонецПопытки; ПечатьТЗ(ТЗ); Возврат ""; КонецФункции // СортировкаРезультатовЗапросаПоИерархии |
|||
14
vde69
26.09.12
✎
09:15
|
(12) если есть транзакция (в том числе скрытая, например проведение документа) и из транзакции вызываешь свои апдейты то все запросы к серверу вызываемые внутри этой транзакции будут "грязными" то есть видеть результат твоих апдейтов.
грязный - это запрос который видет результат незавершенной транзакции, чистый - это запрос который видит состояние бех движений текущей транзакции в 1с ВСЕ запросы грязные |
|||
15
Андрей_Андреич
naïve
26.09.12
✎
09:22
|
(14) тупой отчет. режим сейчас монопольный все окна закрыты. или я не про то?
|
|||
16
vde69
26.09.12
✎
09:25
|
(15) ты в отчете делаешь апдейт??? ну ты и индеец!!!
моя логика была такая 1. ты делешь несколько апдейтов, 2. значит ты обязан делать это в транзакции, иначе ты рискуешь сделать только часть адейтов 3. если есть транзакция - чтение грязное а теперь покажи где я ошибся |
|||
17
Андрей_Андреич
naïve
26.09.12
✎
09:46
|
(16) "ну ты и индеец!!!" - да хоть евреец :)
Я в отчете собрал прямым запросом в таблиицу данные о продажах. Теперь мне надо построить иерархию по группам. Я дернул вошедшие в запрос группы (Id ParentId Descr) из номенклатурника во временную таблицу. Естественно, я могу апдейтить ее хоть 100 раз. Я понимаю, что дурак. Но не понимаю, почему. |
|||
18
ADirks
26.09.12
✎
11:16
|
а ты диагностику от SQL выведи, глядишь и понятно станет чё за фигня
РадугаЗапрос.Отладка(1); РадугаЗапрос.ВыполнитьИнструкцию(ТекстЗапроса,ТЗ); и без попытки + не Сообщить(ОписаниеОшибки()); а Сообщить(РадугаЗапрос.ПолучитьОписаниеОшибки()); |
|||
19
ADirks
26.09.12
✎
11:20
|
там у тебя синтаксические ошибки, а ты и не видишь. Навскидку
|Update "+ТаблицаГрупп+" |Set |Уровень = 0 |,Сортировка = Номенклатура.Descr, Code = Номенклатура.Code |From "+ТаблицаГрупп+" ТаблицаГрупп (NoLock) 2 ошибки: (NoLock) в update - нонсенс; алиас для updatable table - нельзя |
|||
20
Андрей_Андреич
naïve
26.09.12
✎
11:21
|
(18) ошибок не выдает
|
|||
21
Ёпрст
гуру
26.09.12
✎
11:29
|
(19)
алиас для updatable table - нельзя ? Еще как можно! http://msdn.microsoft.com/ru-ru/library/ms177523.aspx |
|||
22
Андрей_Андреич
naïve
26.09.12
✎
11:37
|
(21)Как? Имя, сестра - имя! Я уже через копию сделал, как и в прошлый раз. Некрасиво.
|
|||
23
Ёпрст
гуру
26.09.12
✎
11:39
|
(22) всмысле как ?
алияс для апдейт можно писать.. |
|||
24
Андрей_Андреич
naïve
26.09.12
✎
11:43
|
(23) Вот я и пишу, раз уж разрешили. Не ругается и не апдейтит.
|
|||
25
ADirks
26.09.12
✎
11:44
|
(21) прикольно... и правда можно
а я с чего-то думал, что нет |
|||
26
Андрей_Андреич
naïve
26.09.12
✎
11:45
|
(25) Вот давай вместе и освоим :)
|
|||
27
Ёпрст
гуру
26.09.12
✎
11:46
|
(24) а так ?
|Update Табличка |Set |Табличка.Уровень = 0 |,Табличка.Сортировка = Номенклатура.Descr, Табличка.Code = Номенклатура.Code |From "+ТаблицаГрупп+" Табличка | inner .... left что там у тя дальше по тексту ? |
|||
28
Ёпрст
гуру
26.09.12
✎
11:48
|
так работает ?
|Update Табличка |Set |Табличка.Сортировка = Rtrim(ДопТаблица.Сортировка)+RTrim(ТаблицаГрупп.Сортировка) |From "+ТаблицаГрупп+" Табличка |Left Join "+ТаблицаГрупп+" ДопТаблица (NoLock) On Табличка.ParentId = ДопТаблица.Id |Where Табличка.Уровень=0 |
|||
29
Андрей_Андреич
naïve
26.09.12
✎
11:51
|
(28) Нет
|
|||
30
Андрей_Андреич
naïve
26.09.12
✎
12:02
|
(28) Что-то результат изменился, но чего-то я недоучел. Ща покопаемся.
|
|||
31
Андрей_Андреич
naïve
26.09.12
✎
12:09
|
Ура! Заработало! Спасибо Ёпрст - я бы свой мозг так не вывихнул. Итоговый текст:
|Update "+ТаблицаГрупп+" |Set Уровень=1 |, Сортировка=LTrim(Str(1))+RTrim(Сортировка) |From "+ТаблицаГрупп+" Where ParentId = ' 0 ' | |Set @MaxLevel=1 | |While 1=1 Begin |Update ТаблицаГрупп |Set ТаблицаГрупп.Уровень=@MaxLevel+1, |ТаблицаГрупп.Сортировка = Rtrim(ДопТаблица.Сортировка)+LTrim(Str(@MaxLevel+1))+RTrim(ТаблицаГрупп.Сортировка) |From "+ТаблицаГрупп+" ТаблицаГрупп |Inner Join "+ТаблицаГрупп+" ДопТаблица On ТаблицаГрупп.ParentId = ДопТаблица.Id |Where ТаблицаГрупп.Уровень=0 And ДопТаблица.Уровень=@MaxLevel | If @@RowCount=0 Begin | Break | END | Set @MaxLevel=@MaxLevel+1 |END |
|||
32
Андрей_Андреич
naïve
26.09.12
✎
12:11
|
(28) Оптимизировать это можно / нужно?
|
|||
33
Ёпрст
гуру
26.09.12
✎
12:22
|
(32) дык если работает.. то и забить
:) |
|||
34
Андрей_Андреич
naïve
26.09.12
✎
12:24
|
(33) Так это готовая сортировка справочника по иерахии - я ее во все отчеты вставлять буду.
|
|||
35
ADirks
27.09.12
✎
06:46
|
(34) Тогда подумай лучше вот куда: навесить триггеры на insert/update/delete нужных справочников, чтобы эти твои таблички поддерживать в актуальном состоянии. На каждый справочник своя табличка естественно.
Ещё почитай http://www.1cpp.ru/forum/YaBB.pl?num=1153469047 там правда речь про фильтры, но принцип примерно такой же. |
|||
36
Андрей_Андреич
naïve
27.09.12
✎
07:04
|
(35) Это мне придется на каждый справочник + при создании новых. А тут универсальное, хотя и менее эффективное решение.
Ну и напоследок пожалуюсь. Эта долбаная 1С со своей восьмеркой вдалбливает всем в бошки, что 7.7 умерла и не стоит с ней возиться, а уж развивать тем более. Вот и стараюсь все по минимуму делать. |
|||
37
ADirks
27.09.12
✎
07:19
|
(36) Ну так ты же не ручками это делать будешь, а например так:
//ТБазаДанных:: Функция ПроверитьОбъектыSQLСервера() ... Для н = 1 По Метаданные.Справочник() Цикл МетаСпр = Метаданные.Справочник(н); Состояние("Представление: "+МетаСпр); Если СоздатьПредставление_Справочник(МетаСпр) = 0 Тогда фОшибокНет = 0; КонецЕсли; Если МетаСпр.КоличествоУровней > 1 Тогда Если ТриггерДляИерархии(МетаСпр) = 0 Тогда Возврат 0; КонецЕсли; КонецЕсли; КонецЦикла; ... Возврат 1; КонецФункции Процедура ПриНачалеРаботыСистемы() ВремяПоследнейЗаписи = ""; ФС.АтрибутыФайла(КаталогИБ() + "1cv7.md",,,,, ВремяПоследнейЗаписи); Если ВремяПоследнейЗаписи <> СокрЛП(Константа.ПоследнееИзменениеКонфигурации) Тогда Если МонопольныйРежим() = 1 Тогда оБазаДанных = СоздатьОбъект("ТБазаДанных"); Если оБазаДанных.ПроверитьОбъектыSQLСервера() <> 1 Тогда Возврат 0; КонецЕсли; ФС.ПереименоватьФайл(КаталогИБ()+"TurboMd.prm", КаталогИБ()+"TurboMd.prm~", 1); Константа.ПоследнееИзменениеКонфигурации = ВремяПоследнейЗаписи; ИначеЕсли глФлагОтладки = 1 Тогда Сообщить("Внимание! Время последнего изменения файла конфигурации отличается от записанного в константу!", "!"); Иначе Предупреждение( "Для корректной работы необходим |однократный монопольный вход в систему! |Сообщите об этом администратору!", 15); Возврат 0; КонецЕсли; КонецЕсли; КонецПроцедуры |
|||
38
Андрей_Андреич
naïve
27.09.12
✎
07:33
|
(37) Я же до гуру все равно не дорасту. Моему мозгу и то, что сделал, с трудом дается. К тому же функция заодно после причесывания итоги по группам будет собирать. В общем, я себе комфортную приблуду для отчетиков сделаю и ладушки.
Мне структурное программирование с детства вбили и Ваши ООП туда плохо укладываются. И еще раз огромное спасибо всем участвовавшим в обсуждении. |
|||
39
Mikeware
27.09.12
✎
07:40
|
(38)Собственно, это не ООП, а именно подход структурного программирования...
|
|||
40
ADirks
27.09.12
✎
08:28
|
(38) До гур доростать и не надо. Но расти - обязательно.
Собирать итоги - это кагбе дело собственно отчёта, вспомогательные же таблицы нужны для облегчения этого дела. Т.е. нужен некий баланс затрат: на формирование статических вспомогательных данных и на рассчет оперативных данных. Представь, у тебя с десяток пользователей одновременно запустят отчёты, которые начнут собирать итоги по всем группам, не особо разбирая надо-ненадо, и пихать в таблички к тому же. И всё это будет использовано лишь однократно. А для удобства понапиши лучше процедур для генерации текста запроса - будет гораздо полезней. про ООП уже сказали :) |
|||
41
Андрей_Андреич
naïve
27.09.12
✎
08:33
|
(40) я дико извиняюсь - но если пользователь задал отчет - наверное оно ему надо.
А итоги по группам все равно собирать. Не по всем, а только вошедшим в запрос. Ну и пусть скуль одним запросом 2 дела делает - собирает все группы и итоги по ним. Что-то я тебя не понял. |
|||
42
Mikeware
27.09.12
✎
08:36
|
+(40)"плох тот чайник, который не стремится стать самоваром"©
|
|||
43
ADirks
27.09.12
✎
08:42
|
(41) Не надо писать в таблички однократно используемые данные - это лишняя нагрузка на систему. Многократно же используемые данные надо поддерживать в актуальном состоянии, а не рассчитывать каждый раз.
|
|||
44
Андрей_Андреич
naïve
27.09.12
✎
08:53
|
(43) совершенно согласен, но вот цена вопроса... мне кажется - это и так уже копеечные затраты. Столь глубокой оптимизации мне не надо - на моих объемах все и так летает.
И, этаа... Не бейте меня, а? Ну тоже ведь каждый байтик не вылизываете? |
|||
45
Mikeware
27.09.12
✎
09:01
|
(44) на массовых операциях - иногда приходится и вылизывать...
|
|||
46
Mikeware
27.09.12
✎
09:02
|
+(45) иногда лучше сразу делать правильно...
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |