|
v7: ПроUPDATEить кучу элементов одним запросом (прямые запросы) | ☑ | ||
---|---|---|---|---|
0
monsterZE
24.04.14
✎
12:57
|
Возможен сабж, если у элементов разные значения свойств?
Сейчас апдейчу - 1 элемент-1 запрос.. медленновато =( Элемент - например товар, свойства - цена, остаток |
|||
1
Ёпрст
24.04.14
✎
12:58
|
запросто
|
|||
2
monsterZE
24.04.14
✎
13:00
|
ТекстЗапроса = "
| UPDATE "+ТекСКЛТаб+" | SET | [бла-бла-бла] | IF @@ROWCOUNT = 0 | BEGIN | INSERT INTO "+ТекСКЛТаб+" | [бла-бла-бла] | VALUES | [бла-бла-бла] | END |"; |
|||
3
monsterZE
24.04.14
✎
13:01
|
(1) Запихать все в виртуальную табличку?
|
|||
4
Ёпрст
24.04.14
✎
13:02
|
да просто апдейт из селекта
|
|||
5
Ёпрст
24.04.14
✎
13:02
|
т.е значения для set получать из таблички.. усё.
|
|||
6
Ёпрст
24.04.14
✎
13:04
|
ну, так например (смотри примеры с from внизу)
http://msdn.microsoft.com/ru-ru/library/ms177523.aspx а можешь и коррелированный подзапрос в set пихать еще.. |
|||
7
monsterZE
24.04.14
✎
13:05
|
(5) а пример можно? =) самой конструкции
еще такой момент - апдейчу я внешнюю табличку из 1сы |
|||
8
monsterZE
24.04.14
✎
13:05
|
(6) ок, спс, смотрю =)
|
|||
9
Ёпрст
24.04.14
✎
13:07
|
тип того
update table1 set column1 = ( select max(a) from table2 ) , column1 = ( select max(b) from table3 ) WHERE column3 = c |
|||
10
Ёпрст
24.04.14
✎
13:08
|
или ... иннер джоин и значения со второй таблички..
Ну, вариантов масса |
|||
11
monsterZE
24.04.14
✎
13:25
|
фак =)
а если часть товара присутствует в табличке (и ее надо проапдейтить) а части нет и ее надо заинсертить Чет я не совсем понимаю - у меня WHERE column3 = c в с будет множество объектов т.е. мне надо как-то цикл что-ли =) который бы перебирал объекты и апдейтил их или инсертил |
|||
12
monsterZE
24.04.14
✎
13:28
|
Допустим у меня есть таблица значений, строки которой надо проапдейтить
я чет не совсем представляю - мне надо в текст запроса запихать каждый объект с его свойствами? |
|||
13
Ёпрст
24.04.14
✎
13:30
|
я ж не знаю, откуда ты поля для апдейта тащить собираешься
|
|||
14
Ёпрст
24.04.14
✎
13:32
|
если запрос на sqlite, то там есть insert or replase, для обычного скуля..нужно проверять
|
|||
15
Ёпрст
24.04.14
✎
13:34
|
||||
16
monsterZE
24.04.14
✎
13:36
|
(15) да я так тогда и переписывал
|
|||
17
monsterZE
24.04.14
✎
13:43
|
(13) если из тз
|
|||
18
Ёпрст
24.04.14
✎
13:44
|
(17) ну и ?
А по какому признаку различать, кому и что ?..Или в тзз есть ссылка на объект и значение для реквизита ? |
|||
19
monsterZE
24.04.14
✎
13:46
|
угу. вот ИД надо обновить остальные поля
ТабТовараКОбновлению.НоваяКолонка("РодИД"); ТабТовараКОбновлению.НоваяКолонка("ИД"); ТабТовараКОбновлению.НоваяКолонка("Назван"); ТабТовараКОбновлению.НоваяКолонка("Цена"); ТабТовараКОбновлению.НоваяКолонка("ЕдИзм"); ТабТовараКОбновлению.НоваяКолонка("УпКол"); ТабТовараКОбновлению.НоваяКолонка("Ост"); ТабТовараКОбновлению.НоваяКолонка("Рез"); сейчас я каждый раз подставляю в текст-запроса нужное и Запрос.ВыполнитьСкалярный(ТекстЗапроса); |
|||
20
monsterZE
24.04.14
✎
13:46
|
(19) по ИД
|
|||
21
Ёпрст
24.04.14
✎
13:47
|
тогда ТЗ во временную табличку, а далее примитивно
update t set t.a = vrem.b from table as t inner join #tmptable as vrem on vrem.id = t.id |
|||
22
Ёпрст
24.04.14
✎
13:50
|
на счет укладки тз, тут пример:
http://www.1cpp.ru/forum/YaBB.pl?num=1170322440/7#7 |
|||
23
monsterZE
24.04.14
✎
13:52
|
такой еще вопрос - текст запроса (для 1с++) по размеру имеет какие-то ограничения? если все значения сразу в него запихать.
|
|||
24
Ёпрст
24.04.14
✎
13:55
|
Попробуй, только смысл ?
|
|||
25
Ёпрст
24.04.14
✎
13:56
|
и ограничение есть, только не помню, какое.
|
|||
26
monsterZE
24.04.14
✎
14:00
|
(24) не, ну чтобы заполнить временную табличку - это-ж тоже время (если также в цикле ее заполнять)
а для меня как раз самое главное время сэкономить |
|||
27
Ёпрст
24.04.14
✎
14:01
|
ну, не больше времени займёт, чем заполнение текста запроса.
|
|||
28
Ёпрст
24.04.14
✎
14:02
|
и это, Ост ты же откуда то получаешь ?
И наверняка, тоже с запроса, вот и клади в нём сразу или сразу апдейт.. |
|||
29
КонецЦикла
24.04.14
✎
14:03
|
||||
30
monsterZE
24.04.14
✎
14:03
|
(28) спасибо за инфу, буду пробывать =)
|
|||
31
monsterZE
24.04.14
✎
14:04
|
(29) благодарю! =)
|
|||
32
ADirks
24.04.14
✎
14:33
|
что касается вставить только то, чего нет, то например так
insert into dest_table ... from src_table ... where src_table.ID not in (select ID from dest_table) |
|||
33
Ёпрст
24.04.14
✎
14:34
|
(32) как в (15) красившее и быстрее..
|
|||
34
Ёпрст
24.04.14
✎
14:34
|
по идее :)
|
|||
35
ADirks
24.04.14
✎
14:44
|
типа того?
insert into dest_table ... from src_table ... where not exists (select * from dest_table where dest_table.ID = src_table.ID) да, как минимум не медленее. просто не люблю коррелированные запросы. эстет, панимаишь :) |
|||
36
Ёпрст
24.04.14
✎
14:47
|
(35) не-не-не, никаких коррелированных!
trad : обычно пишу так |UPDATE ... |IF @@ROWCOUNT = 0 | INSERT ... и не парюсь |
|||
37
Ёпрст
24.04.14
✎
14:48
|
тупо проверка на количество проапдейтенных строк..
:) красиво |
|||
38
Ёпрст
24.04.14
✎
14:50
|
Хотя.. если не надо апдейтить, то что есть, тогда да..тогда проверка селектом
|
|||
39
ADirks
24.04.14
✎
14:52
|
Так это если одна строка, или все строки из src отсутствуют в dest. А если часть строк из src уже есть в dest?
|
|||
40
Ёпрст
24.04.14
✎
14:53
|
(39) тады ой :)
|
|||
41
Ёпрст
24.04.14
✎
14:54
|
хотя непонятно, чего не реализовать было как в sqlite конструкцию insert or replace в скуле
|
|||
42
monsterZE
24.04.14
✎
16:04
|
собрал все, что мне надо запросом теперь апдейтить =)
ТекстЗапроса = " |SELECT | LTRIM(СпрРод.Code) as РодКод | ,LTRIM(СпрТов.Code) as Код //| ,СпрТов.ID as [Товар $Справочник.Товары] | ,СпрТов.Descr as Имя | ,$СпрТов.Опт_Цена as Цена | ,$СпрТов.БазоваяЕдиница as [БазЕд $Перечисление.ЕдиницыИзмерения] | ,$СпрТов.СтоимостьСборки as УпКол | ,ТОст.Ост as Остаток | ,ТРез.Рез as Резерв |FROM | $Справочник.Товары as СпрТов (NOLOCK) |LEFT JOIN |(SELECT | РегОст.Товар as ТовИД | ,РегОст.ОстатокТовараОстаток as Ост |FROM | $РегистрОстатки.ОстаткиТоваров(,, | Склад = :ВыбСклад AND Товар IN (SELECT Val FROM #Группа), | (Товар),(ОстатокТовара)) as РегОст) as ТОст ON ТОст.ТовИД = СпрТов.ID |LEFT JOIN |(SELECT | РегРез.Товар as ТовИД | ,РегРез.РезервТовараОстаток as Рез |FROM | $РегистрОстатки.РезервыТоваров(,, | Склад = :ВыбСклад AND Товар IN (SELECT Val FROM #Группа), | (Товар),(РезервТовара)) as РегРез) as ТРез ON ТРез.ТовИД = СпрТов.ID |LEFT JOIN | $Справочник.Товары as СпрРод (NOLOCK) ON СпрРод.ID = СпрТов.PARENTID |WHERE | СпрТов.ID IN (SELECT Val FROM #Группа) |"; |
|||
43
Serginio1
24.04.14
✎
16:13
|
(35) Смотри Merge
http://msdn.microsoft.com/ru-ru/library/bb522522(v=sql.105).aspx |
|||
44
monsterZE
24.04.14
✎
16:16
|
как теперь еще в один селект обернуть? =)
типа иф екзист в дест_таб.ид подзапрос.ид then апдейт else инсерт |
|||
45
monsterZE
24.04.14
✎
16:25
|
(43) о! =)
что-то типа MERGE Target AS T USING (Подзапрос) AS S ON (Target.Код = S.Код) WHEN NOT MATCHED BY TARGET THEN INSERT(цена, остаток) VALUES(S.Цена, S.Остаток) WHEN MATCHED THEN UPDATE SET T.Цена = S.Цена, T.Остаток = S.Остаток |
|||
46
Serginio1
24.04.14
✎
16:25
|
||||
47
Ёпрст
24.04.14
✎
16:26
|
(43) ага, только вот с кокой версии то оно появилось ? :)
|
|||
48
Serginio1
24.04.14
✎
16:27
|
(47) 2008
|
|||
49
monsterZE
24.04.14
✎
16:27
|
(47) умеешь поддержать =)
|
|||
50
monsterZE
24.04.14
✎
16:28
|
а.. не 2008 тоже есть!
|
|||
51
Ёпрст
24.04.14
✎
16:29
|
(48) во-во.. а у аутора поди 2000 или 2005 :)
|
|||
52
monsterZE
24.04.14
✎
16:30
|
(51) 2008R2 8-P
|
|||
53
Ёпрст
24.04.14
✎
16:32
|
повезло значит
|
|||
54
Ёпрст
24.04.14
✎
16:33
|
там кстати, есть и инсерт через новый синтаксис.. и ранжирующие функции и .. много еще чего :)
|
|||
55
Serginio1
24.04.14
✎
16:41
|
(54) Да вкусненьки этот 2008.
Ну и уже 6 лет прошло. А 2005 это вообще переходный вариант. |
|||
56
monsterZE
24.04.14
✎
17:16
|
факардо! =) у меня целевая табличка лежит в отдельной бд
|
|||
57
monsterZE
24.04.14
✎
17:20
|
дописал путь.. в инсерте и апдейте его тож надо дописать?
пока просто, чтобы проверить как оно вобще =) ТекстЗапроса = " |MERGE [Magazin].[dbo].["+ТекСКЛТаб+"] AS Целевая |USING (SELECT | LTRIM(СпрРод.Code) as РодКод | ,LTRIM(СпрТов.Code) as Код //| ,СпрТов.ID as [Товар $Справочник.Товары] | ,СпрТов.Descr as Имя | ,$СпрТов.Опт_Цена as Цена | ,$СпрТов.БазоваяЕдиница as [БазЕд $Перечисление.ЕдиницыИзмерения] | ,$СпрТов.СтоимостьСборки as УпКол | ,ТОст.Ост as Остаток | ,ТРез.Рез as Резерв | FROM | $Справочник.Товары as СпрТов (NOLOCK) | LEFT JOIN | (SELECT | РегОст.Товар as ТовИД | ,РегОст.ОстатокТовараОстаток as Ост | FROM | $РегистрОстатки.ОстаткиТоваров(,, | Склад = :ВыбСклад AND Товар IN (SELECT Val FROM #Группа), | (Товар),(ОстатокТовара)) as РегОст) as ТОст ON ТОст.ТовИД = СпрТов.ID | LEFT JOIN | (SELECT | РегРез.Товар as ТовИД | ,РегРез.РезервТовараОстаток as Рез | FROM | $РегистрОстатки.РезервыТоваров(,, | Склад = :ВыбСклад AND Товар IN (SELECT Val FROM #Группа), | (Товар),(РезервТовара)) as РегРез) as ТРез ON ТРез.ТовИД = СпрТов.ID | LEFT JOIN | $Справочник.Товары as СпрРод (NOLOCK) ON СпрРод.ID = СпрТов.PARENTID | WHERE | СпрТов.ID IN (SELECT Val FROM #Группа)) AS Источник |ON (Целевая.id = Источник.Код) |WHEN NOT MATCHED BY TARGET | THEN INSERT(parent_id,id,nazvan,cena,up_ed,up_kol,ostatok,rezerv,izmenost) | VALUES(Источник.РодКод | ,Источник.Код | ,Источник.Имя | ,Источник.Цена | ,Источник.БазЕд | ,Источник.УпКол | ,Источник.Остаток | ,Источник.Резерв | ,:Маркер) |WHEN MATCHED | THEN UPDATE SET | parent_id = Источник.РодКод | ,nazvan = Источник.Имя | ,cena = Источник.Цена | ,up_ed = Источник.БазЕд | ,up_kol = Источник.УпКол | ,ostatok = Источник.Остаток | ,rezerv = Источник.Резерв | ,izmenost = :Маркер |; |"; |
|||
58
Serginio1
24.04.14
✎
17:27
|
Я Ну можно еще проверить на изменение полей
|MERGE into dbo."+СтрРегПрайсов.ИмяТаблицыХранения+" as ИзменяемыеПрайсы |Using #TempPrice as Источник"; Стр=Стр+" | ON Источник.Артикул=ИзменяемыеПрайсы."+РегПрайсовПоля.Артикул+" | and @Прайс=ИзменяемыеПрайсы."+РегПрайсовПоля.ТипЦен+" | and Источник.Мейк = ИзменяемыеПрайсы."+РегПрайсовПоля.Мейк+" | When MATCHED AND (@Импорт<>ИзменяемыеПрайсы."+РегПрайсовПоля.Импорт+СтрРавнения+") Then | Update Set ИзменяемыеПрайсы."+РегПрайсовПоля.Импорт+"=@Импорт"+СтрУстановки+" | When NOT MATCHED THEN |INSERT(" |
|||
59
monsterZE
24.04.14
✎
17:29
|
(58) да пока ругается на
State 42000, native 1038, message [Microsoft][ODBC SQL Server Driver][SQL Server]Имя объекта или столбца отсутствует или пусто. Убедитесь, что каждый из столбцов в инструкции SELECT INTO имеет имя. Для других инструкций проверьте наличие пустых имен-псевдонимов. Не допускаются псевдонимы, |
|||
60
Serginio1
24.04.14
✎
17:38
|
,IsNull(ТОст.Ост,0) as Остаток
| ,IsNull(ТРез.Рез,0) as Резерв |
|||
61
monsterZE
24.04.14
✎
17:38
|
косячу =)
|
|||
62
monsterZE
24.04.14
✎
17:38
|
имя таблички закоментил
|
|||
63
monsterZE
24.04.14
✎
17:48
|
теперь чем-то не нравится имя столбца
Недопустимое имя столбца "БазЕд". |
|||
64
Ёпрст
24.04.14
✎
17:53
|
(63)
$СпрТов.БазоваяЕдиница as [БазЕд $Перечисление.ЕдиницыИзмерения] выкини типизацию на ..х |
|||
65
monsterZE
24.04.14
✎
17:55
|
выкинул - заработало
но нах мне там абра-кадабра =) как ее к нормальному виду привести? |
|||
66
monsterZE
24.04.14
✎
18:01
|
не джойнить же справочник единиц и выдерать из него дескр =\\\
|
|||
67
Serginio1
24.04.14
✎
18:02
|
Из метаданных сделай табличку соотвествия ID и Наименования
мд=СоздатьОбъект("MetaDataWork"); |
|||
68
monsterZE
24.04.14
✎
18:09
|
(67) ок, завтра продолжу =)
куясе оно работает.. быстрее минимум раз в 10, чем старый вариант |
|||
69
Serginio1
24.04.14
✎
18:11
|
||||
70
monsterZE
24.04.14
✎
18:16
|
(69) угу, спасибо! =)
такой еще вопрос - это если я пользую 1с под Sa я могу любую табличку прямым запросом править? в том смысле - раньше я сначала подключался к ней, потом возвращался к текущей. Запрос.УстБД(ОДБЦ_ДБ); [...] ОДБЦ_ДБ.Закрыть(); Запрос.УстБД1С(); |
|||
71
Serginio1
24.04.14
✎
18:16
|
Уже не помню но где то 10 тичный а где то и 36 значчный ID используется
ИД36=мд.ЧислоВСтроку(мд.ИДОбъекта(МДПеречисление),36); |
|||
72
Serginio1
24.04.14
✎
18:17
|
Да можешь.
|
|||
73
monsterZE
24.04.14
✎
18:21
|
(72) прост у меня возникла мысль, что возможно еще из-за соединения медленно работало.. а достаточно было имя бд указать
|
|||
74
Serginio1
24.04.14
✎
18:33
|
(73) Ну при записи по одной строке у тебя идет поиск по номеру каждый раз, при MERGE используется индекс в двух таблицах и проходят по индексам двух таблиц.
Это аналогично алгоритму сортировки слиянием. Плюс все в одной транзакции |
|||
75
monsterZE
24.04.14
✎
18:37
|
(74) завтра из интереса попробую без организации соединения
просто по имяБД.Табличка а в целом - кароч надо все переписывать потихоньку =) зы. очередной раз спасибо за помощь! |
|||
76
spock
24.04.14
✎
19:26
|
Когда же вы на v8х перейдете?
|
|||
77
monsterZE
25.04.14
✎
09:31
|
(76) чтобы "нам" перейти на 8 - надо нанимать штат программеров и писак кфкг с нуля.. и желательно еще скрестить ее с бухией =) (и потом еще переучивать 100 чел операторов.. которые как роботы с одной программой) а это будет стоить дорого.. а дорого платить никто не хочет. тут давятся из-за процентов перевоплощения ип в ооо, а ты говоришь "когда перейдете" =) ..немного оффтопика
|
|||
78
monsterZE
25.04.14
✎
09:32
|
*писать
|
|||
79
Serginio1
25.04.14
✎
10:36
|
(76) Кстати эта ветка показывает то чего нельзя сделать в v8х. В 1С++ можешь использовать всю мощь T-SQL. А в 8ке нужно извращаться как v8: Подзапросы с Выбрать Первые либо писать прямые запросы.
|
|||
80
monsterZE
25.04.14
✎
10:41
|
(75) проверил, использование соединения видимых ограничений в скорости не накладывает. запросы пуляются ровно такое-же количество времени.
*продолжаю наблюдения* =)) |
|||
81
monsterZE
25.04.14
✎
11:51
|
собрал табличку соответ.
чтобы пользовать ее в запросе, это надо временную создавать и заполнять ее значениями? ТабСоотЕдИзм = СоздатьОбъект("ТаблицаЗначений"); ТабСоотЕдИзм.Очистить(); ТабСоотЕдИзм.НоваяКолонка("Ид36"); ТабСоотЕдИзм.НоваяКолонка("Ед"); ТабСоотЕдИзм.НоваяКолонка("Пред"); Для ъ=1 По Метаданные.Перечисление("ЕдиницыИзмерения").Значение() Цикл МетаЗнач = Метаданные.Перечисление("ЕдиницыИзмерения").Значение(ъ); ТабСоотЕдИзм.НоваяСтрока(); ТабСоотЕдИзм.Ид36 = МД.ЧислоВСтроку(МД.ИДОбъекта(МетаЗнач),36); ТабСоотЕдИзм.Ед = МетаЗнач.Идентификатор; ТабСоотЕдИзм.Пред = МетаЗнач.Представление; КонецЦикла; --- добавил еще один джойн по Единицам, чтобы забрать Descr.. | LEFT JOIN | $Справочник.Единицы as СпрЕд (NOLOCK) ON (СпрЕд.PARENTEXT = СпрТов.ID) AND ($СпрЕд.Единица = $СпрТов.БазоваяЕдиница) |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |