Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

Удаление записей регистра сведений напрямую из SQL

Удаление записей регистра сведений напрямую из SQL
Я
   Bibr
 
19.10.20 - 17:26
Хочу проконсультироваться с общественностью на предмет удаления записей регистра сведений напрямую через SQL-запрос.
Регистр сведений подчинён регистратору, периодичность - по позиции регистратора.
Достаточно ли запроса конструкции "DELETE FROM WHERE" к таблице регистра, нет ли каких подводных камней??


п.с. превентивно на вопрос "нафига"
Необходимо удалить некоторые записи регистра (почистить базу, убрать в архив). После чего регистраторы будут закрыты для редактирования.
Но регистраторы содержат большое количество строк и конструкция
НаборЗаписей.Отбор.Регистратор.Установить(стр.Регистратор);
НаборЗаписей.Прочитать();
   piter3
 
1 - 19.10.20 - 17:29
Камень-обьект не найден. Нет контроля ссылочной целостности.
   Bibr
 
2 - 19.10.20 - 17:30
(1) непонятно. какой объект где не найден?
запись регистра сведений - не ссылочный тип данных
   piter3
 
3 - 19.10.20 - 17:30
Конфа, какие РС и так далее
   piter3
 
4 - 19.10.20 - 17:32
Давай подробнее, а то я вот о своем подумал)
   Жан Пердежон
 
5 - 19.10.20 - 17:33
таблицы итогов, если есть обновить надо,
изменения планов обменов, опять же, если есть
зачем тебе НаборЗаписей.Прочитать(); если ты удаляешь?
если удаляешь не все записи у документа - еще и нумерацию обновлять
   Bibr
 
6 - 19.10.20 - 17:35
(4) судя по сообщениям, вы мне вряд ли поможете :)
без обид :)
А так-то в (0) всё написано.
   Bibr
 
7 - 19.10.20 - 17:37
(5) Во, спасибо.
А вот это верно.
Так-то 1С сама нумерацию правит.
А если не контролить нумерацию и не обновлять, что будет?
   Bibr
 
8 - 19.10.20 - 17:42
+(0) кстати, не всё сообщение  скопировалось
Но регистраторы содержат большое количество строк и конструкция
НаборЗаписей.Отбор.Регистратор.Установить(стр.Регистратор);
НаборЗаписей.Прочитать(); 
с последующим поиском, удаление записью работает критически медленно. Поэтому смотрю в сторону прямого sql-запроса.
Насчёт лицензионного соглашения и запрета работы с sql напрямую в курсе.
   Said_We
 
9 - 19.10.20 - 17:43
(7) Предположу, что ничего не будет, если нумерацию не править. 1С эту нумерацию вставляет. Но к номеру вряд-ли что-то привязывается. В логике программы никогда не видел привязки к номеру движения.
   fisher
 
10 - 19.10.20 - 17:48
Насчет нумерации не понял. Какую нумерацию обновлять придется? Зачем?
   Said_We
 
11 - 19.10.20 - 17:51
(8) "с последующим поиском" - а если сразу все найти, а не по одной? Вот тогда номер записи понадобиться, что бы удалять было быстрее.
   Bibr
 
12 - 19.10.20 - 17:51
(10) в физической таблице регистра сведений есть поле "LineNo", куда пишется то, что в 1С в регистре называется "номер строки"
   Надо работать
 
13 - 19.10.20 - 17:52
(0) достаточно. Но если записей очень много - лучше перенести с даты, потом грохнуть табличку
   Надо работать
 
14 - 19.10.20 - 17:53
потом пересчитать итоги, если оны есть у регистра (но скорее всего нет)
   Said_We
 
15 - 19.10.20 - 17:54
(0) Рассказывай подробнее каков критерий удаления строк. Т.е. какие строки оставлять в наборе необходимо и какие удалять.
Предположу, что самый долгий процесс у тебя некий поиск.
   Bibr
 
16 - 19.10.20 - 17:57
(11) основное время всё равно съедает НаборЗаписей.Прочитать() да и нет у регистра сведений методов удаления сразу всех записей))
(15) нет, поиск по критериям милисекунды работает, 80% съедает НаборЗаписей.Прочитать() и НаборЗаписей.Записать()
   Said_We
 
17 - 19.10.20 - 17:59
(16) Запись пустого набора - это сразу всех по регистратору удалить.
Если знаешь какие записи должны быть, то сразу заполняй набор без чтения необходимыми записями и записывай.
   Bibr
 
18 - 19.10.20 - 17:59
(13) перенести с даты не получается, увы но в регистраторах надо выборочно..
(14) у регистров сведений какие итоги???
   Надо работать
 
19 - 19.10.20 - 18:00
(18) самые натуральные итоги
   Жан Пердежон
 
20 - 19.10.20 - 18:00
(16) прочитать можешь запросом сразу все записи всех документов, которые надо оставить;
НаборЗаписей.Записать() без НаборЗаписей.Прочитать() "удалит" все записи регистратора
   Надо работать
 
21 - 19.10.20 - 18:01
   Bibr
 
22 - 19.10.20 - 18:03
(17) (20) надо попробовать. Но возможны ситуации, когда у регистратора 100 000 записей. Надо удалить 500.
Считывание, заполнение и запись 99500 много времени тоже займёт.
   Said_We
 
23 - 19.10.20 - 18:04
(18) Периодические РС погут содержать срез самых первых и срез самых последних.
   Bibr
 
24 - 19.10.20 - 18:04
(21) спасибо, изучу.
   Said_We
 
25 - 19.10.20 - 18:12
(22) т.е. возможны ситуации, когда по регистратору ничего удалять не нужно.
   Bibr
 
26 - 20.10.20 - 17:42
(23) не, этот без итогов.
(25) всегда нужно что-то удалять, но нередки ситуации, когда нужно удалить немного записей из большого массива.

(21) Спасибо, дельная статья.
Сделал через прямой запрос - летает.
Нумерация движений сбита, но потестил - вроде не критично, не увидел, чтобы где-то это могло вылезти боком.
Так что останавливаюсь на этом варианте.
   Конструктор1С
 
27 - 20.10.20 - 18:31
если нужно удалить много записей в регистре (больше половины), то лучше сделать копию таблицы, в неё синсертить все записи, которые должны остаться. Потом на место основной таблицы поставить копию с залитыми записями. INSERT выполняется быстрее, чем DELETE
   Конструктор1С
 
28 - 20.10.20 - 18:36
А если уж удаляешь записи по условию, то удобно использовать оператор MERGE. Через него можно и нумерацию строк набора записей обновить, попутно удаляя лишние записе в наборе

https://docs.microsoft.com/ru-ru/sql/t-sql/statements/merge-transact-sql?view=sql-server-ver15
   timurhv
 
29 - 20.10.20 - 19:01
(22) Так не считывайте записи, получайте один раз запросом с условием по регистратору и записывайте.
Быстрее выйдет, не знаю насколько это будет существенно для вас.
   Жан Пердежон
 
30 - 21.10.20 - 03:37
(26) нумерация:

UPDATE
    _InfoRg31
SET
    _LineNo = TT.NewLineNo
FROM
    (SELECT REG1._RecorderTRef, REG1._RecorderRRef, REG1._LineNo, SUM(1) NewLineNo
    FROM _InfoRg31 REG1, _InfoRg31 REG2
    WHERE REG1._RecorderTRef = REG2._RecorderTRef AND REG1._RecorderRRef = REG2._RecorderRRef AND REG1._LineNo>=REG2._LineNo
    GROUP BY REG1._RecorderTRef, REG1._RecorderRRef, REG1._LineNo
    HAVING REG1._LineNo <> SUM(1)) TT

WHERE
    _InfoRg31._RecorderTRef = TT._RecorderTRef AND _InfoRg31._RecorderRRef = TT._RecorderRRef  AND _InfoRg31._LineNo = TT._LineNo
 
 Рекламное место пустует
   SleepyHead
 
31 - 21.10.20 - 05:32
(0) Посмотри, что происходит в типовых при записи набора сведений. Часто обновляются "вторичные" регистры. В ЗУП это интервальные регистры, самый простой пример - регистр, где хранятся статусы налогоплательщиков НДФЛ (резидент, нерезидент). При изменениях в этом регистре переформировываются записи в интервальном регистре, который потом используется в отчетности.

Так что запросто можешь порушить логику конкретной конфы.
   Bibr
 
32 - 21.10.20 - 09:47
(28) Интересно, спасибо.

(29) А получить 1 раз запросом - это не считывание?)))
Я как раз в (22) и описывал этот вариант. Регистратор содержит 100000 записей, надо удалить 50.
Выборка запросом 99950 записей, заполнение нового Набора 99950 записей, плюс собственно Запись. Медленно. Тогда как удалить надо 50.

(30) Класс, сохранил, спасибо! *ПалецВверх*

(31) Спасибо.
   Said_We
 
33 - 21.10.20 - 10:24
(30) А примерно так отработает нумерация или нет? т.е. с использованием ROW_NUMBER() а без использования декартового умножения.

(
SELECT
    t._RecorderTRef as _RecorderTRef
   ,t._RecorderRRef as _RecorderRRef
   ,t._LineNo as _LineNo
   ,t.NewLineNo as NewLineNo
from
  (SELECT
    t._RecorderTRef as _RecorderTRef
   ,t._RecorderRRef as _RecorderRRef
   ,t._LineNo as _LineNo
   ,ROW_NUMBER() OVER(ORDER BY t._LineNo) as NewLineNo
  FROM _InfoRg31 as t
  ) as t
where t._LineNo <> t.NewLineNo
) AS TT
   Said_We
 
34 - 21.10.20 - 10:34
Или как-то так:

(
SELECT
    t._RecorderTRef as _RecorderTRef
   ,t._RecorderRRef as _RecorderRRef
   ,t._LineNo as _LineNo
   ,t.NewLineNo as NewLineNo
from
  (SELECT
    t._RecorderTRef as _RecorderTRef
   ,t._RecorderRRef as _RecorderRRef
   ,t._LineNo as _LineNo
   ,ROW_NUMBER() OVER(partition by t._RecorderTRef, t._RecorderRRef  ORDER BY t._LineNo) as NewLineNo
  FROM _InfoRg31 as t
  ) as t
where t._LineNo <> t.NewLineNo
) AS TT
   Said_We
 
35 - 21.10.20 - 12:08
Это подзапрос вместо подзапроса ТТ в (30).
Если отработает, то отработать должен на много быстрее чем в (30).
   Serginio1
 
36 - 21.10.20 - 12:26
   Said_We
 
37 - 21.10.20 - 12:33
(36) Тут нет перевода запроса на другой язык. Тут на прямую запрос к таблицам базы SQL. Считай, что тут нет 1С вообще.
   Serginio1
 
38 - 21.10.20 - 12:45
(37) Ну как это нет?
v8: Перевод Запроса 1С в SQL?
Там как раз пример получения имен таблиц и полей!
   Serginio1
 
39 - 21.10.20 - 12:46
пост 40
 Но можно дописать. например для среза последних
Функция СоздатьТекстСрезПоследних(ИменаГрупСтр,ИменаРесурсовСтр,Регистр)
   Said_We
 
40 - 21.10.20 - 12:52
(38) В (0) нет такой задачи. В (0) не спрашивает как имя таблицы узнать и имена полей и т.д.
Пока не спрашивает. :-) А может и не спросит - на прямую на SQL рисовать будет.
   Жан Пердежон
 
41 - 21.10.20 - 13:05
(34) похоже на правду, не уверен только, что в субд тс оконные функции так же реализованы
   Said_We
 
42 - 21.10.20 - 13:09
(41) "субд тс" - что такое "тс"?
   Жан Пердежон
 
43 - 21.10.20 - 13:15
ТС — Топик-стартер, автор темы
   СвинТуз
 
44 - 21.10.20 - 13:26
Неандертальцы ломают 1С? А зачем?
Ходят слухи, к документам можно приписать движения. В том числе и пустые.
Долго записываются движения даже одного документа по одному регистру?
   СвинТуз
 
45 - 21.10.20 - 13:29
НаборЗаписей.Прочитать();

Следующая строка :
НаборЗаписей.Очистить(); ?
   Said_We
 
46 - 21.10.20 - 13:29
(41) В MS, PostgreSQL, Oracle есть функция ROW_NUMBER() c OVER() и т.д.
   Said_We
 
47 - 21.10.20 - 13:30
(45) Почитай ветку с самого начала внимательнее. У (0) долго этот процесс очень выполняется, так как много всего он удаляет.
   kovalev_oleg
 
48 - 21.10.20 - 13:31
Да с регистрами сведений просто, нашел таблицу и грохаешь записи по условию в консоли SQL, подводные камни -ограничение по дате поставь  по организации  не забудь про смещение дат
   kovalev_oleg
 
49 - 21.10.20 - 13:40
(1) на самом деле так же просто можно удалить и регистры накопления ,   сложности возникнут с регистрами бухгалтерии,  дело в том что там  к каждой таблице прикреплена еще одна таблица с субконто и также же сложности с документами и справочниками   каждая табличная часть это отдельная таблица  связаны они все по уникальными идентификаторам
   СвинТуз
 
50 - 21.10.20 - 14:11
(49)
В регистрах накопления не две таблицы?
   timurhv
 
51 - 21.10.20 - 14:22
(49) при пометке на удаление\распроведении документов и очистке их движений не стоит забывать про таблицы журналов.
   kovalev_oleg
 
52 - 21.10.20 - 15:05
(50) что Вы имеете ввиду ?  Таблицу изменений ?


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.