Решение проблем с неуникальными записями при переводе 1С 7.7 на SQL

25.05.10

База данных - Чистка данных

Иногда во время перевода DBF базы на SQL возникает ошибка связанная с наличием в таблицах нескольких записей с одинаковым идентификатором DOCID или ID.  Загрузка вылетает с ошибкой, так как SQL сервер не может создать уникальный индекс. Приложенный скрипт помогает бороться с этой проблемой.

Скачать файл

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование По подписке [?] Купить один файл
delete_all_duble!!! no select.sql
.sql 3,41Kb
57
57 Скачать (1 SM) Купить за 1 850 руб.

Такая ситуация возникает когда по какой-то причине(сбитые индексы, например) в DBF базе создаются идентичные записи в таблицах. Пока база в DBF - этого не заметно и работать не мешает, но в SQL такая база не пролезает.

Предлагаемая методика такова:

1. Запускаем стандартно загрузку данных.

2. После вылетания загрузки с ошибкой открываем Enterprise Manager и запускаем приложенный скрипт. Скрипт удалит дубли строк в журналах, документах, справочниках, регистрах.

3. После выполнения скрипта запускаем программу монопольно - 1С закончит создание индексов и запустится. Далее следует самостоятельно перерассчитать итоги либо встроенными средствами 1С либо,  обработкой "ПересчетИтоговРегистров.ert"  (от: Ермоленко В.В.).

4. Радуемся что не пришлось делать всякого рода длительные тестирования и исправления в базе DBF.

Все, база готова!

Для решения проблемы можно, конечно, предварительно удалить дубли сразу в DBF базе перед выгрузкой, но как правило о наличии проблемы узнаем уже когда база выгружена и даже наполовину загружена в SQL, так что предлагаемая методика получается быстрее.

 

Сам скрипт:

 

go
exec('delete from  _1SJOURN  where row_id <  (Select max(row_id) from _1SJOURN as t1   where _1SJOURN.iddoc = t1.iddoc);')
go
  SET NOCOUNT on
  DECLARE @DBName char(30)
  DECLARE @coun int
  DECLARE SysCur CURSOR FOR SELECT name  FROM    sysobjects WHERE     (xtype = 'u') AND (name LIKE 'dt%')
  OPEN SysCur
  FETCH NEXT FROM SysCur INTO @DBName
  WHILE @@FETCH_STATUS=0 BEGIN
    if @DBName <>'dtproperties                  '
    begin   
    exec ('alter table '+@DBName+' add id int identity(1,1);  ')
    exec ('delete from '+@DBName+' where id < (Select max(id) from '+@DBName+' as t1   where '+@DBName+'.iddoc = t1.iddoc and '+@DBName+'.lineno_ = t1.lineno_); ')
    set @coun=@@ROWCOUNT
    exec ('alter table '+@DBName+' drop column id; ')
         PRINT 'Base ' +@DBName+'  '+CAST(@coun AS CHAR(4)) +' records deleted'
    end
     FETCH NEXT FROM SysCur INTO @DBName
  END
  CLOSE SysCur
  DEALLOCATE SysCur
go
  SET NOCOUNT on
  DECLARE @DBName char(30)
  DECLARE @coun int
  DECLARE SysCur CURSOR FOR SELECT name  FROM    sysobjects WHERE     (xtype = 'u') AND (name LIKE 'dh%')
  OPEN SysCur
  FETCH NEXT FROM SysCur INTO @DBName
  WHILE @@FETCH_STATUS=0 BEGIN
    if @DBName <>'dtproperties                  '
    begin   
    exec ('alter table '+@DBName+' add id int identity(1,1);  ')
    exec ('delete from '+@DBName+' where id < (Select max(id) from '+@DBName+' as t1   where '+@DBName+'.iddoc = t1.iddoc); ')
    set @coun=@@ROWCOUNT
    exec ('alter table '+@DBName+' drop column id; ')
         PRINT 'Base ' +@DBName+'  '+CAST(@coun AS CHAR(4)) +' records deleted'
    end
     FETCH NEXT FROM SysCur INTO @DBName
  END
  CLOSE SysCur
  DEALLOCATE SysCur
go

  SET NOCOUNT on
  DECLARE @DBName char(30)
  DECLARE @coun int
  DECLARE SysCur CURSOR FOR SELECT name  FROM    sysobjects WHERE     (xtype = 'u') AND (name LIKE 'ra%')
  OPEN SysCur
  FETCH NEXT FROM SysCur INTO @DBName
  WHILE @@FETCH_STATUS=0 BEGIN
    exec ('alter table '+@DBName+' add id int identity(1,1);  ')
    exec ('delete from '+@DBName+' where id < (Select max(id) from '+@DBName+' as t1   where '+@DBName+'.iddoc = t1.iddoc and '+@DBName+'.actno = t1.actno); ')
    set @coun=@@ROWCOUNT
    exec ('alter table '+@DBName+' drop column id; ')
     PRINT 'Base ' +@DBName+'  '+CAST(@coun AS CHAR(4)) +' records deleted'
     FETCH NEXT FROM SysCur INTO @DBName
  END
  CLOSE SysCur
  DEALLOCATE SysCur
go

  SET NOCOUNT on
  DECLARE @DBName char(30)
  DECLARE @coun int
  DECLARE SysCur CURSOR FOR SELECT name  FROM    sysobjects WHERE     (xtype = 'u') AND (name LIKE 'sc%')
  OPEN SysCur
  FETCH NEXT FROM SysCur INTO @DBName
  WHILE @@FETCH_STATUS=0 BEGIN
    exec('delete from ' +@DBName+'  where row_id <  (Select max(row_id) from ' +@DBName+' as t1   where ' +@DBName+'.id = t1.id);')
    set @coun=@@ROWCOUNT
         PRINT 'Base ' +@DBName+'  '+CAST(@coun AS CHAR(4)) +' records deleted'
     FETCH NEXT FROM SysCur INTO @DBName
  END
  CLOSE SysCur
  DEALLOCATE SysCur

go


delete from _1SENTRY where row_id < (Select max(row_id) from _1SENTRY as t1 where _1SENTRY.docid = t1.docid and _1SENTRY.number = t1.number);
PRINT 'Base _1SENTRY '+CAST(@@ROWCOUNT AS CHAR(4)) +' records deleted'
go


delete from _1Soper where row_id < (Select max(row_id) from _1Soper as t1 where _1Soper.docid = t1.docid)
PRINT 'Base _1Soper '+CAST(@@ROWCOUNT AS CHAR(4)) +' records deleted'
go

См. также

Чистка данных Пользователь Оперативный учет 7.7 1С:Торговля и склад 7.7 Абонемент ($m)

Установка пометки на удаление справочника Номенклатура. Торговля 77. 9.2.

1 стартмани

21.11.2022    2659    3    Sevg    0    

2

Чистка данных Программист Пользователь Платформа 1С v7.7 1С:Бухгалтерия 7.7 1С:Зарплата и кадры 7.7 1С:Торговля и склад 7.7 Россия Абонемент ($m)

Обработка для поиска и пометки на удаление дублирующихся элементов произвольного справочника.

1 стартмани

12.09.2022    3129    9    tetraren    0    

2

Свертка базы Чистка данных Перенос данных 1C Системный администратор Программист Платформа 1С v7.7 1С:Комплексная 7.7 1С:Торговля и склад 7.7 Абонемент ($m)

Приводится порядок действий для создания новой информационной базы на основе имеющейся файл-серверной "Торговля и Склад" ред.9.2, для учёта с нуля. В новую базу выполняется перенос справочников и остатков номенклатуры. Журналы документов, данные регистров, долги контрагентов, партии очищаются.

1 стартмани

14.01.2022    6450    6    etmarket    3    

4

Чистка данных Корректировка данных Программист Пользователь Платформа 1С v7.7 Конфигурации 1cv7 Абонемент ($m)

Архив различных обработок 1С 7.7 с открытым исходным кодом для работы с данными при свертке, выгрузке, исправлении, модификации информационной базы. Можно использовать любую обработку в качестве заготовки для добавления собственных функций.

1 стартмани

13.05.2021    8156    12    etmarket    0    

3

Чистка данных Программист Платформа 1С v7.7 Конфигурации 1cv7 Абонемент ($m)

Эта обработка позволяет удалить созданные системой элементы справочников. Например, когда элементы создаются при тестировании и исправлении базы с наименованиями, включающими строку "ФС". Обработка тестировалась на базе конфигурации Бухгалтерский учет для Казахстана, редакции 7.70.257.

10 стартмани

26.03.2021    8701    2    softmaker    0    

0

Поиск данных Чистка данных Логистика, склад и ТМЦ Программист Оперативный учет 7.7 1С:Торговля и склад 7.7 Управленческий учет Абонемент ($m)

Простая и удобная обработка предназначена для поиска и исправления задублированных (повторяющихся) номенклатурных штрихкодов справочника Единицы. Также она даёт возможность посмотреть номенклатурные остатки. Полезна в случаях, когда номенклатура сопоставляется по штрихкоду с другими внешними источниками, а именно с модулем "Обмент ГИСМТ".

1 стартмани

19.11.2020    7924    1    Kuzya_brаtsk    4    

8

Чистка данных Системный администратор Программист Платформа 1С v7.7 Конфигурации 1cv7 Абонемент ($m)

Когда удаляются документы и элементы справочников в 1С 7.7 через удаление помеченных на удаление объектов, запись из dbf файла не удаляется, она помечается как удаленная, но физически остается в файле. Если эти помеченные на удаление записи удалить физически, то размер файлов значительно уменьшится.

1 стартмани

18.10.2018    16158    48    evg520750    5    

1
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Ёпрст 1065 25.05.10 12:07 Сейчас в теме
Всё это конечно хорошо, но что мешает сделать ТиИ в дбф базе перед выгрузкой ?

Или проверить прямым запросом дубли в самой дбф базе ?
2. Ёпрст 1065 25.05.10 12:08 Сейчас в теме
+1 да, и где гарантия того, что в скуль база уже целиком загрузилась ?
3. maxis33 45 25.05.10 13:00 Сейчас в теме
В sql сначала загружаются все данные, а затем уже начинают создаваться индексы, во время которых уже и вылетает программа. Следовательно данные на этот момент уже загружены.

На большой базе ТиИ идет долго, к тому же как написано выше "Для решения проблемы можно, конечно, предварительно удалить дубли сразу в DBF базе перед выгрузкой, но как правило о наличии проблемы узнаем уже когда база выгружена и даже наполовину загружена в SQL, так что предлагаемая методика получается быстрее."
4. Ёпрст 1065 25.05.10 13:09 Сейчас в теме
(3) забыл еще про операции и проводки
5. maxis33 45 25.05.10 14:36 Сейчас в теме
(4) Нужды небыло;) вот для операций и проводок еще можно добавить

go
delete  from _1SENTRY where row_id < (Select max(row_id) from _1SENTRY as t1   where _1SENTRY.docid = t1.docid and _1SENTRY.number = t1.number);
   PRINT 'Base _1SENTRY  '+CAST(@@ROWCOUNT  AS CHAR(4)) +' records deleted'
go
delete  from _1Soper  where row_id < (Select max(row_id)  from _1Soper as t1                where _1Soper.docid = t1.docid)
   PRINT 'Base _1Soper  '+CAST(@@ROWCOUNT  AS CHAR(4)) +' records deleted'
go
6. Ёпрст 1065 25.05.10 14:54 Сейчас в теме
(5) ну, не у всех же оперучет один.. в бухне очень часто проводки "двоятся"

а в справочниках, при определенных условиях, так вообще интерактивными действиями можно создать элемент с дублирующимся id !
7. Ёпрст 1065 25.05.10 14:54 Сейчас в теме
ну и бух итоги еще придётся пересчитать..
8. Ёпрст 1065 25.05.10 14:55 Сейчас в теме
+8 да..и еще пересчет итогов по колонкам..
13. maxis33 45 26.05.10 12:15 Сейчас в теме
(8) Пересчет служебных данных потом нужен, это да..
9. leov-001 25 25.05.10 15:42 Сейчас в теме
Вам принцип работы показали, остальное сами доделывайте для своих нужд.
С DBF отлично работает 1sqlite
http://www.1cpp.ru/forum/YaBB.pl?num=1192855975/0#0
http://www.1cpp.ru/forum/YaBB.pl?num=1214205575/0
10. Ёпрст 1065 25.05.10 16:08 Сейчас в теме
(9) Это к кому адресовано сообщение ?
Если мне, то скрипты такие ужо и так давно есть у меня..
А для дбф конкретно в этом случае 1sqlite вообще не катит - не умеет он апдейтить и удалять, только селект, если что.

11. Abadonna 3968 25.05.10 21:06 Сейчас в теме
(9)
Вам принцип работы показали, остальное сами доделывайте для своих нужд.

Это ты Ёпрст-у что ли написал? :D
Хоть бы в профайл заглянул до того, как...
12. virs 26.05.10 09:38 Сейчас в теме
А, что Ёпрст-у уже и написать ничего не моги...?
14. anc2002 13.01.12 18:09 Сейчас в теме
однако, на одной ненормальной базе и данный скрипт не помог, пришлось вырезать из базы проблемные типы документов и записывать их в базу sql через выгрузку загрузку
15. nextkmv 129 11.03.14 12:17 Сейчас в теме
Спасибо большое! За день до дня X dbf версия выдала ошибка -120 и приказала переходить на sql(размер dbf файла 1,99 Гб). При загрузке базы в SQL выкинул ошибку о не уникальности индекса, а ведь день X уже пришел. Искать виновника в dbf версии не было времени и эта обработка нас спасла.
16. rystenko 04.10.22 06:05 Сейчас в теме
Спасибо огромное автору... Да даже через более чем 10 лет после публикации приходится сталкиваться с задачей перевода 7.7 на sql :) И этот скрипт сэкономил мне изрядно нервов и сил.
Оставьте свое сообщение