Имя: Пароль:
1C
 
Редактирование записей SQL из 1С
, , ,
0 yurii-syrkin
 
22.08.18
18:14
Всем здравствуйте. Скорее всего информации на эту тему много, но я ничего не нашёл применительно к моему случаю. Итак, необходимо в огромном количестве документов установить значение реквизита Подразделение. Силами 1С эта операция выполнялась неделю и завершилась процентов на 10. Решил попробовать напрямую в SQL. Подразделение это ссылка и на уровне SQL имеет тип массив. То есть просто текстовым запросом через UPDATE решить не получается, ну или я не понимаю как это сделать. Подскажите пожалуйста как это реализовать.
1 Cyberhawk
 
22.08.18
18:35
Так тебе потом пади еще и в движениях документов надо подразделение будет добавить?
2 Cyberhawk
 
22.08.18
18:35
А если нет, то что у тебя там 10 недель работает, не ясно. Кривизна рук скорее всего.
3 Cyberhawk
 
22.08.18
18:36
Как устанавливешь рассказывай, и забудь про СКЛ
4 Вафель
 
22.08.18
18:38
основная проблема в том что документы потом нужно перепровести. вот на это все время и уйдет все равно
5 yurii-syrkin
 
22.08.18
18:39
Нет, в движениях пока ничего делать не надо. Просто документы разных типов. Каждого типа примерно от 100000 до 300000. Днём пользователи работают. Обработку приходится запускать по ночам
6 Cyberhawk
 
22.08.18
18:47
Замер времени делал?
7 Cyberhawk
 
22.08.18
18:47
И что там за база - биллинг что ли или консолидированная какая?
8 yurii-syrkin
 
22.08.18
18:50
Да, консолидированная, по нескольким филиалам, самописная. Да замер делал, ничего особенно тормозящего нет, просто много документов.
9 Cyberhawk
 
22.08.18
18:51
Показывай код тогда
10 Cyberhawk
 
22.08.18
18:51
100 объектов в секунду в одном потоке можно писать в БД - факт
11 Вафель
 
22.08.18
18:55
чтоб апдейт сделать тебе нужно бинари предстваление гуида узнать.Его узнать можно в талице справочника подразделения
12 МихаилМ
 
22.08.18
19:02
(0)
в какой субд у Вас есть тип массив ?
13 yurii-syrkin
 
22.08.18
19:06
(11) Да, я этот бинари определяю запросом. В 1С он имеет тип COMSafeArry
14 yurii-syrkin
 
22.08.18
19:06
СУБД MS SQL 2014
15 ERWINS
 
22.08.18
19:08
сделай update
минут 10, не больше
16 ERWINS
 
22.08.18
19:09
в 1с есть функция показывающая в как именуются поля
17 yurii-syrkin
 
22.08.18
19:09
Код:
ТекстЗапроса = "USE [" + мИмяБазы + "]
                    |GO
                    |    
                    |UPDATE [dbo].[_" + СтрТаблицаОбъектов.ИмяТаблицыSQL + "]
                       |SET [_" + СтрТаблицаОбъектов.ИмяПоляSQL + "] = <_IDRRef, binary(16),>    
                    | WHERE <Условия поиска,,>
                    |GO"

Только непонятно что писать в условии и в SET.
В условии надо написать типа <> Справочник.ПодразделенияОрганизаций.ПустаяСсылка(), а в SET Справочник.ПодразделенияОрганизаций.НайтиПоКоду("0000005")
18 yurii-syrkin
 
22.08.18
19:11
(15) Да это понятно, что быстро. Как быть с ссылочными типами?
19 Cyberhawk
 
22.08.18
19:11
Да не, зачем ты код прямого запроса показываешь
Показывай код, который у тебя неделю работал
20 yurii-syrkin
 
22.08.18
19:14
(19) Да что его показывать то
Для Каждого СтрТаблицаДокументов Из ТаблицаДокументов Цикл
   ДокументОбъект = СтрТаблицаДокументов.ДокументСсылка.ПолучитьОбъект();
   ДокументОбъект.Подразделение = Подразделение;
   ДокументОбъект.ОбменДанными.Загрузка = Истина;
   ДокументОбъект.Записать();
КонецЦикла;
21 vitkhv
 
22.08.18
19:19
(13) COMsafearay это ты через ADO  получаешь, по умолчанию. А так там обычный bynary16 в апдейте будет так set fldxxxref = 0x0000000000000000
Здесь почитай там обсуждение и ссылки как с 1с таблицами и данными работать напрямую из mssql http://www.sql.ru/forum/1289996-a/dannye-1s
22 nicxxx
 
22.08.18
19:19
ничего сложного
запускаешь обработку http://catalog.mista.ru/public/147147/
находишь имя таблицы справочника подразделений
делаешь запрос SELECT * FROM _ReferenceXXX WHERE _code = '0000005'
берешь из результата поле _IDRRef, помещаешь его в свой запрос в секцию SET
в секцию WHERE если надо условие, исключающее пустую ссылку, надо написать WHERE _fldXXX <> 0x00000000000000000000000000000000
здесь _fldXXX  - имя поля Подразделение в документе
23 vitkhv
 
22.08.18
19:25
(22) мне кажется уж лучше сразу инструменты разработчика скачать, там все есть, чем эти отдельные обработки.
24 yurii-syrkin
 
22.08.18
19:27
(22) Да просмотреть поля можно и без обработки. Также перебрал ПолучитьСтруктуруХраненияБазыДанных(). Вот получается Result.Fields("_IDRRef").Value в таблице подразделений возвращает COMSafeArry в отладчике. Когда на нем нажимаю F2 открывается массив из 16 элементов, каждый из которых число 2-3 знаков.
25 yurii-syrkin
 
22.08.18
19:29
Как этот массив запросом UPDATE записать в строки таблиц документов? Имя таблиц документов и имя поля "Подразделение" на уровне SQL уже известны
26 vitkhv
 
22.08.18
19:31
(25) это не массив, это ado массив возращает
27 ebttlh
 
22.08.18
19:32
(0) не занимайся дичью. Разбей на несколько потоков и записывай в транзакции по 5000 элементов. Все на 1с ессно
28 yurii-syrkin
 
22.08.18
19:34
(27) Да ляжет база. Она с одним то потоком кряхтит
29 vitkhv
 
22.08.18
19:35
(25)Делаешь селект к справочнику подразделения, находишь idrref нужного подразделения, копирует его в буфер. И в апдейт в секцию set fldxxx =  0х0000000000000, вместо 0x000000000000 вставляешь значение из буфера. Запускаешь и радуешься.
30 yurii-syrkin
 
22.08.18
19:36
Да и вообще, комрадам думаю интересно будет узнать как напрямую в SQL записывать ссылочные типы
31 ebttlh
 
22.08.18
19:36
(28) апгрейдь железо
32 ebttlh
 
22.08.18
19:37
(30) это долбоебизм и мне неинтересно
33 vitkhv
 
22.08.18
19:38
(30) уже давно все пережевано,я ж тебе даже ссылку дал. А ты тут про какой-то простой апдейт
34 vitkhv
 
22.08.18
19:39
(30) там по ссылке как idrref самому генерировать без 1с и чтоб 1с их хамала, без падения производительности.
35 vitkhv
 
22.08.18
19:41
(30) я обмены пишу на уровне mssql между базами 1с. Сам на уровне mssql документы создаю в 1с. Уже на этом столько тумаков понабивал, что пипец
36 ebttlh
 
22.08.18
19:43
(35) сколько баз убил?
37 yurii-syrkin
 
22.08.18
19:43
(35) Быстро получается?
38 vitkhv
 
22.08.18
19:45
(36) нисколько.
(37) моментально. Там же в тесте и время показано инсертов.

Не я один такой, кто напрямую обмены на уровне nssqk пишет.
39 vitkhv
 
22.08.18
19:46
(38) mssql грёбаный т9
40 Cyberhawk
 
22.08.18
19:50
(20) Доп. свойства устанавливать еще надо, на которые завязаны, например, всякие подписки / обмены. Что за конфа-то?
41 youalex
 
22.08.18
20:01
(0) >> Подразделение это ссылка и на уровне SQL имеет тип массив.

Это где такое есть,тип массив?
42 vitkhv
 
22.08.18
20:03
(41) это ado так ему возвращает. Она по умолчанию бинарники в массивах возращает
43 vitkhv
 
22.08.18
20:05
(40) ему ещё их надо будет в таблицу изменений прописать, как я понял из его кода, что бы по обмену ушло.
44 youalex
 
22.08.18
20:27
Если коды (или наименования. или любое другое "родное" скулю поле) уникальны для подразделений, то можно не преобразовывать, как вариант сделать через переменные, типа:

declare @podr1 binary = (Select _idref from _RefПодразделения Where code ='001')

и дальше в апдейте использовать их.

но проще их тупо выдернуть селектом и тупо проставить литералами.
45 nicxxx
 
22.08.18
20:38
(44) ему уже 2 раза об этом сказали. человек с 2009 года на форуме.....
46 Cyberhawk
 
22.08.18
20:40
(43) Это можно, наверное, и потом сделать. По всем объектам, где подразделение заполнено )
47 Franchiser
 
гуру
22.08.18
21:32
Проще ИР запустить, план запроса посмотреть
48 vitkhv
 
22.08.18
21:33
(45) конечно если топикастер пошёл сложным путем с адо, а не тупо отрыл ssms и не сделал то, что ему советуют, то ему лучше с прямыми апдейтами не шутить.
49 vitkhv
 
22.08.18
21:37
(46) можно и потом. Но если топикастер рассчитывает, что он адейтнит табличку заголовков документа и все дальше само как в 1С, то он глубоко ошибается. 1С не использует триггеры севера БД и все необходимые события обрабатывает сама.
50 Salimbek
 
22.08.18
22:26
(27) Поддерживаю.
(28) Ну конечно, ты же заставляешь систему записывать данные после каждого документа. А если по 5000 документов, которые будут заполнены в доли секунды, потом фиксируешь транзакцию, что займет пару секунд, т.к. и блокировка будет один раз наложена и писать будет сразу блок данных, что проще оптимизатору и диску. И в разные сессии лучше раскидать работу с разными типами документов, тогда не будет взаимных блокировок.
51 Cyberhawk
 
22.08.18
22:42
"в разные сессии лучше раскидать работу с разными типами документов, тогда не будет взаимных блокировок" // Если документы не входят в последовательность, бгг
52 vitkhv
 
22.08.18
22:44
(50)Даже если будет делать по 5000 в одной транзакции, сильно делу не поможет, такой уж mssql сервер. А если у автора ссд так вообще ни о чем.
53 Salimbek
 
22.08.18
23:46
(52) Тестировал? Я вот, на файловой Рознице тестировал: без транзакции загрузка 70000 записей занимала минут 5-10, в транзакции - несколько секунд. Объемов как в (0) у меня нет, но что мешает автору потестить?
(51) Так ведь у него чистая запись без проведения вроде? Я предположил, что там только таблицы самих документов будут затрагиваться. Но спорить не буду, не проверял.
54 nicxxx
 
23.08.18
01:06
(53) Написано же "mssql server". Причем тут твоя файловая розница? В серверной версии похрену, в транзакции на 5000 строк запись будет или по-одной.
55 vitkhv
 
23.08.18
03:38
(54)так рождаются мифы )))
56 vitkhv
 
23.08.18
03:43
(53) я все тестирую.
С таким поведением mssql столкнулся ещё во времена 77, когда на dbf в транзакции получали суперускорение, а на серверной версии ничего. Тогда же читал и объсняние этому феномену. С тех пор ничего не изменилось.
57 Nikoss
 
23.08.18
06:18
(56) так и какое объяснение этому феномену?

И что вообще подразумевается под поднятием "записать в транзакции"? НачатьТранзакцию -> запись 5000 документов -> ЗафиксироватьТранзакцию?
58 ADirks
 
23.08.18
06:50
(0) Берёшь Profiler, записываешь штатно 1 документ, смотришь на запросы, которые 1С шлёт. По образу и подобию пишешь апдейты.
59 vitkhv
 
23.08.18
07:36
(57) что-то с эксклюзивностью доступа, если я правильно помню.
60 vitkhv
 
23.08.18
07:38
(58) начнет 1С в тот момент config опрашивать ну и проапдейтит его автор гыгы
61 vitkhv
 
23.08.18
07:51
(57) именно это и подразумевает.
62 ADirks
 
23.08.18
08:19
(57) в DBF (в семёрке) так транзакционный механизм устроен. До завершения транзакции всё пишется в отдельные файлы, а при завершении пачкой вкидывается в основные файлы. И это драматически быстрее, чем обычный способ записи. Но опять же, надо без фанатизма, т.к. при большом размере транзакции эффект м.б. и обратным.

(60) да и ладно, мне не жалко
ещё есть прикольная шутка про rm -rf /
63 vitkhv
 
23.08.18
08:35
(62) значит правильно помню. Фактически доступ эксклюзивный, на запись. Видимо и в файловой версии 1с 8 также.
64 Salimbek
 
23.08.18
11:09
(62) А для mssql тоже подтверждаешь, что транзакции не ускоряют? Я вот (63)-му не верю, а тебе - верю.
65 ebttlh
 
23.08.18
11:14
(64) Зачем кому-то верить, если можно самому проверить??? Записывать в транзакции порциями и многопоточная обработка это офиц. рекомендация 1С с ИТС, и она блеать работает! Ускоряет в неск. десятков раз. Вместо этого тут развели какую-то гомосятину.
66 ebttlh
 
23.08.18
11:22
У автора железо дохлое, предлагать лечить это прямыми запросами это идиотизм.
67 timurhv
 
23.08.18
11:26
(0) Вы делаете поиск и замену? Какое условие отбора документов по подразделениям?
(65) Во-первых, будут блокировки пользователям.
Во-вторых, SQL-запрос все-равно быстрее.
68 rphosts
 
23.08.18
11:28
(0)>Подразделение это ссылка и на уровне SQL имеет тип массив.
Ссылка из 1С на сиквеле это никакой не массив

(8) Ну так запусти в 100500 нитей одновременно если как ты рассказываешь ни во что не упирается.
69 rphosts
 
23.08.18
11:29
(60) ну если и на это нет знаний - лучше вообще не лезть в базу: база целее будет
70 rsv
 
23.08.18
11:29
(0) ...если такой путь решения то откройте штатный sql ms и выполнитн update.Он не сложный.
71 ebttlh
 
23.08.18
11:31
(67) Во-первых если документ не будет проводиться, то не будет никаких блокировок. Во-вторых 1С сама и отправляет этот самый SQL-запрос. Херню не несите.
72 timurhv
 
23.08.18
11:39
(71) С первым утверждением согласен. Со вторым - нет, хотя бы потому что мы получаем объект и на практике разница будет заметна на больших объемах в х10-100 раз.
73 nicxxx
 
23.08.18
11:41
(66) Как раз из-за дохлого железа прямыми запросами будет быстрее
74 unregistered
 
23.08.18
11:49
Запустить фоновыми заданиями в несколько потоков порциями по 100 - 500 документов. И пусть себе шелестит потихонечку. Хоть всю неделю. В худшем случае пользователи чуть подвисать будут при работе в некоторых операциях.

Прямым запросом конечно будет быстрее, но делать следует осторожно, чтобы быть уверенным, что всё делается корректно - меняется нужное поле, на нужное значение и нет необходимости обновлять никакие связанные поля и таблицы (планы обменов, записи в регистрах, последовательностях и пр.).
75 Жан Пердежон
 
23.08.18
11:53
(0) Что за конфа, и что за доки, если не секрет?
Смотрел какие доки и почему медленно пишутся, что у тебя происходит при записи? Может ещё что-то стоит добавить в ДопСвойства?
76 Cyberhawk
 
23.08.18
11:57
(75) Повторюша
77 vitkhv
 
23.08.18
11:58
(64) Так это для тебя предмет веры. Ну верь дальше. Я с верующими не спорю.
78 vitkhv
 
23.08.18
11:59
(65) многопоточная обработка, естественно ускоряет. В одном потоке вы там хоть убейтесь, нифига не добъетесь.
79 vitkhv
 
23.08.18
12:02
(65) У меня разузлование и расчет себестоимости в нескольких потоках идут. Так тут скорость прямо пропорционально зависит от количества ядер. Пока диски не станут затыкаться.
80 Salimbek
 
23.08.18
12:16
(77) Ты чего докопался? Ну да, я тебе НЕ верю на 100%, и именно потому, что это НЕ предмет веры. А далее есть авторитет, и именно поэтому я твое мнение услышал и принял к сведению, но прошу подтверждения у более авторитетного человека. А Дрикса я еще по 1с++ знаю и потому его мнение для меня будет практически 100% достоверно. А твое я так НА ВЕРУ не приму, ты уж извини.
81 vitkhv
 
23.08.18
12:47
(80)ну раз вы верите человеку так как пересекались на этом форуме по 1С++. То тогда уж зацените мои художества на ToySQL прародительнице 1С++ в части доступа к MSSQL http://www.sql.ru/forum/231377/sortirovka-v-zaprose-po-chislovomu-polu?hl=

с той поры много воды утекло.
82 Borteg
 
23.08.18
12:56
(20) ни транзакции ни потоков на такую базу где 100-300к документов разных видов?
83 Salimbek
 
23.08.18
13:09
(81) Опять логическая ошибка. Верю не потому, что "пересекались на этом форуме по 1С++", а по уровню продемонстрированных знаний.
На этом предлагаю закончить эту неблагодарную тему.
84 ADirks
 
23.08.18
13:09
(64) Для SQL версии, насколько я помню, эффект был, когда остатки штатными запросами считались. Т.е. на клиенте кэшировались остатки по регистрам. А так используется транзакционный механизм MS SQL, и ему без разницы размер транзакции (лишь бы transaction log с tempdb не лопнули).
Поскольку в моих конфах практически нет штатных запросов, то я разницы не наблюдаю.

Ну и так уж доверяешь ты мне зря :)
Всё надо проверять.
85 vitkhv
 
23.08.18
13:28
(84)да на 77 есть метод выборки из регистров не помню как называется, никакие прямые запросы не могли превзойти. Правда если на ТА. Если задним числом перепроводить, тогда все, только прямые запросы.
86 vitkhv
 
23.08.18
13:35
(83) да только высказался ты прям по станиславскому.
(84) это называется "не сотвори себе кумира" или "доверяй но проверяй"