Имя: Пароль:
1C
1C 7.7
v7: insert into, values, select, подзапрос
,
0 Eeakie
 
04.12.15
01:31
Всем доброй ночи.
Есть запрос, который даёт определенное количество строк с пятью значениями в каждой. Надо создать новый элемент справочника и эти пять значений занести в элемент. Как это сделать? В двух словах..
1 Eeakie
 
04.12.15
01:55
Видимо, придётся ждать до завтра.
2 lxndr
 
04.12.15
04:11
3 Ёпрст
 
04.12.15
07:16
найти максимальный id справочника и прибавлять 1-ку в inserte
4 фобка
 
04.12.15
07:31
В элементе справочника ТЧ нет, поэтому только в строке хранить внутреннее представление
5 Тихий омут
 
04.12.15
08:09
(0) +(3) ток помни, что ид - он то ведь 36ричный. и кстати, уриб есть? справочник мигрирует?
6 Eeakie
 
04.12.15
10:55
(5) УРИБ нет. Перевод 36to10 где-то видел.

Вопрос больше к синтаксису. Представим, что у нас есть выборка:
|select
|   $Спр.Количество,
|   $Спр.Цена
|from
|   $Справочник.Справочник1 as Спр with (nolock)";

Предположим, что в результате в выборке 10 строк. Вот как конкретно их засунуть в другой справочник, где есть только id, descr, Количество и Цена? Пример никто дать не может?
7 НЕА123
 
04.12.15
11:01
(5)+
иерархический? тип, длина кода? и т.д.
ЗЫ
"В двух словах.."
8 НЕА123
 
04.12.15
11:03
(6)
эээ...
тогда (7) может и сторно.
но я бы все-рвно по-честному добавлял...
9 Eeakie
 
04.12.15
11:03
(7) Думал проще будет :) Иерархии нет, код (число, 8), наименование (текст, 1).
10 Eeakie
 
04.12.15
11:04
+(9) Количество (число, 10, 3), Цена (число, 17, 2)
11 Eeakie
 
04.12.15
11:14
Я может как-то непонятно спросил.

|insert into $Справочник.Справочник1 (Количество, Цена)
|values (10, 20.5)

Как в вэльюс подставить свои значения из запроса? Конечно, можно сделать из запроса ТЗ и перебором построчно выполнять этот текст, но в выборке 450к+ строк. Это, похоже, будет надолго.
12 ADirks
 
04.12.15
11:18
insert into $Справочник.Справочник1 (Количество, Цена)
select
   Количество, Цена
from
   ...
13 Eeakie
 
04.12.15
11:22
(12) Неправильный синтаксис возле from ©
14 Eeakie
 
04.12.15
11:24
(12)
|insert into $Справочник.Справочник1 (Количество, Цена)
|select
|   $Спр.Количество as Количество,
|   $Спр.Цена as Цена
|from
|   $Справочник.Справочник1 as Спр with (nolock)

Прямо вот так?
15 Это_mike
 
04.12.15
11:29
(13) дык values потерял...
16 Eeakie
 
04.12.15
11:33
(15)
insert into $Справочник.Справочник1 (Количество, Цена)
values (Выборка.Количество, Выборка.Цена)
from(
   select
      .. as Количество,
      .. as Цена
   from
      ...
   ) as Выборка

Получается так?
17 Это_mike
 
04.12.15
11:39
Не, похоже я загнался...
посмотри в BOL, там примеры есть
insert into $Справочник.Справочник1 ($Справочник.Справочник1.Количество, $Справочник.Справочник1.Цена)
   select
      .. as Количество,
      .. as Цена
   from
      ...
18 ADirks
 
04.12.15
11:41
в (14) правильно
ну, с точки зрения синтаксиса, конечно
19 Eeakie
 
04.12.15
11:43
(17), (18), Спасибо. Хоть какие-то другие ошибки стали вылазить :)
20 Это_mike
 
04.12.15
11:44
(19) "никогда не ищи ошибки, если не знаешь, что с ними делать дальше..."©
21 Eeakie
 
04.12.15
11:56
(18) Я извиняюсь, а с какой точки зрения там неправильно?
22 ADirks
 
04.12.15
12:10
(21) ну ты же ошибки видишь, которые "стали вылазить"
23 Eeakie
 
04.12.15
12:13
(22) Вижу и теперь еще больше вопросов..
24 Это_mike
 
04.12.15
12:15
(23) см (20) :-)))
25 Eeakie
 
04.12.15
12:15
+(22) Ругается, что я хочу в поле numeric(18, 3) хочу вставить NULL, а поле NOT NULL. Фигня в том, что Количество из подзапроса не может быть NULL. 0 - еще куда ни шло, но точно не NULL.
26 Eeakie
 
04.12.15
12:15
(24) Тут одни Ванги собрались :)
27 Eeakie
 
04.12.15
14:10
Невозможно вставить повторяющуюся ключевую строку в объект "dbo.SC8548" с уникальным индексом "IDD"
Как побороть?
28 Это_mike
 
04.12.15
14:13
вставлять уникальную, вестимо.
у тебя у реквизита - контроль уникальности
29 trad
 
04.12.15
14:15
(27) наверно, все же лучше пойти по пути:
Спр.Новый()
Спр.Записать()
30 Eeakie
 
04.12.15
14:15
(28) Я контроль уникальности вообще убрал из справочника.
31 Eeakie
 
04.12.15
14:16
(29) Нееет. Надо уже доразбираться.
32 Это_mike
 
04.12.15
14:17
(31) "нас невозможно сбить с пути - нам пофигу, куда идти"©?
33 Это_mike
 
04.12.15
14:17
(27) ну так индекс ИДД по чему уникален? по иду? значит, вставляешь с тем же идом...
34 Eeakie
 
04.12.15
14:30
(33) Так а где выставляется id + 1? В инсерте или в селекте?

(select max(dbo.Convert36to10(Спр.id)) + 1 from $Справочник.СтрокиЗаявок as Спр with (nolock)) as id
35 trad
 
04.12.15
14:34
(34) вот ты так пишешь.
а прикидывал что будет если такой insert+select запустят одновременно 2+ пользователя?
36 Это_mike
 
04.12.15
14:35
(34) жуть какая... wms лепишь, чтоль?
37 Это_mike
 
04.12.15
14:36
(35) "ты вот сейчас матом ругаешься, а потом будешь этими же руками хлеб брать!"© :-))
38 Eeakie
 
04.12.15
14:41
(35) Одновременно запускаться не будет.
(36) Лучше не спрашивай :)
(35), (36), может лучше что-то толковое скажете?
39 Это_mike
 
04.12.15
14:42
(38) сделай хранимку, которая будет новый ид возвращать... и ее используй
40 Это_mike
 
04.12.15
14:42
баян, в общем...
41 Это_mike
 
04.12.15
14:44
вообще, даже я ( :-)) о как я сказанул!) не люблю создавать  элементы и документы напрямую....
42 Eeakie
 
04.12.15
14:51
(39) Бляха, я вот совсем не в курсе про эту "хранимку". Что за оно?
(41) А может действительно нафиг эти прямые записи в таблицы? Просто очень уж долго штатно заполняет полмиллиона записей.. и примерно раз в неделю их еще и обновлять надо..
43 НЕА123
 
04.12.15
14:53
(42)
в транзакции
?
44 Это_mike
 
04.12.15
15:00
(42) чойто типпо
CREATE FUNCTION NewId() Returns char(9)
Begin
@ret = select ltrim(dbo.convert10to36(max(dbo.convert36to10(left (id,6)))+1)+'   ') from $Справочник.xxxxx
End
45 Eeakie
 
04.12.15
15:04
(43) И в транзакции не очень-то быстро.
(44) Хм.. попробую.
46 trad
 
04.12.15
15:06
еще какая то хранимка - лишнее тут
47 trad
 
04.12.15
15:07
в этом запросе
(select max(dbo.Convert36to10(Спр.id)) + 1 from $Справочник.СтрокиЗаявок as Спр with (nolock)) as id

во-первых надо блокировать:
вместо (nolock) нужно (updlock)
при этом если insert/select не в одном выражение, то нужно обернуть транзакцией

во-вторых нужно помнить об индексах и накладывать блокировку на диапазон ключа индекса, а не на всю таблицу
поэтому нужно писать так: dbo.Convert36to10(max(Спр.id))
сравни планы выполнения двух запросов
select max(dbo.Convert36to10(Спр.id)) + 1 from $Справочник.СтрокиЗаявок as Спр with (nolock)
select dbo.Convert36to10(max(Спр.id)) + 1 from $Справочник.СтрокиЗаявок as Спр with (nolock)
думаю поймешь о чем я
48 Это_mike
 
04.12.15
15:07
(46) можно и в подзапрос. но лень....
49 trad
 
04.12.15
15:08
для быстрой вставки поищи примеры использования SQLLock из 1cpp.dll - он спецом для этого был придуман
50 НЕА123
 
04.12.15
15:09
(45)
> И в транзакции не очень-то быстро.
сколько в 1 транзакции элементов?
51 trad
 
04.12.15
15:10
а вообще самый скоростной и экстремальный способ вставки - bulk insert
52 Это_mike
 
04.12.15
15:15
(47) да и без плана понятно, что лажанулся...
53 ADirks
 
04.12.15
15:15
Если каждый день надо полмиллиона записей лопатить, то может подумать о том, чтобы свою табличку завести?
Заодно правильные индексы можно сделать.
54 Eeakie
 
04.12.15
15:29
(47) Спасибо за разъяснение. Похоже, там еще много чего кроме этого надо знать.
(53) Изначально стоял вопрос в обычном отчете, который должен был брать ТЧ нескольких документов, брать товар, его цены из периодики, потом конвертить в валюту и считать сроки оплаты (и там еще хренова туча условий на отбор). Первоначальный запрос оказался вполне себе здоровым с и работал не очень быстро (пытался оптимизировать, но безуспешно). После чего было решено замутить отдельный справочник с основными данными по ТЧ, и обрабатывать уже их. И вроде бы всё ничего, но данные в ТЧ могут меняться задним числом, что приводит к неточностям. Поэтому справочник надо перезаполнять периодически. Не за весь период, конечно, но за последний год хотя бы (могут править некоторые моменты в течении года). Так вот за последний год получается ~500k строк в выборке и их надо перезаписать в справочник, а длится это достаточно долго. Пробовал update, но исходя из того, что меняться могут не только цены, но и Товар и Документ, решил, что проще удалить последний год и просто перезаполнить. Вот отсюда вся эта дребедень.
Возможно, есть какой-то более простой способ организации этого всего, но я его не нашел.
55 trad
 
04.12.15
15:37
(54) для реализации такого хранилища лучше прислушаться к (53)
56 Eeakie
 
04.12.15
15:40
(55) Честно говоря, для меня "завести свою табличку" и "сделать правильные индексы" звучит не сильно знакомо :\
57 Eeakie
 
04.12.15
15:51
(53), (55), дайте ссыль, если не трудно, где хоть что-то по этой теме будет объяснено. Пока оставлю всё на Новый() + Записать(), а со временем попробую перевести на "доступный" для скуля язык.
58 Это_mike
 
04.12.15
15:58
(57) BOL:
create table
create index
59 Eeakie
 
04.12.15
15:59
(58) technet чтоль?
60 Это_mike
 
04.12.15
16:01
(59) Book OnLine, ставится прямо вместе с SQL...
61 Eeakie
 
04.12.15
16:02
(60) На технете/мсдн аналог просто. Спасибо.
62 trad
 
04.12.15
16:59
(57) пока изучаешь работу со своей таблицей, можешь свой алгоритм с Новый+Записать немного модифицировать под SQLLock
Пример тут
http://www.1cpp.ru/docum/icpp/html/ODBC.html#sqllock