ДИСКЛЕЙМЕР
Автор не несет никакой ответственности, кроме как за достоверность предоставленной информации.
Всю нижеследующую информацию воспринимать и использовать на свой страх и риск.
После вступительной части была получена база, которая нормально открывалась (как в конфигураторе, так и в режиме предприятия), аварийное завершение с записью дампа спровоцировать не получалось - это уже было намного лучше, чем первоначальное состояние.
Но и работать с базой было нельзя. Открытие формы констант, определенных документов, попытка обновить конфигурацию ИБ и другие обычные действия - давали исключения уровня СУБД с добровольно-принудительным предложением завершить работу :) Читайте ниже о том, как я победил каждое из них.
Примеры ошибок и приёмы лечения
Проблема №1. Нехватка поля (реквизита объекта либо константы)
Симптомы:
При попытке открыть форму объекта/констант/etc видим
Ошибка СУБД:
Microsoft OLE DB Provider for SQL Server: Invalid column name '_Fld123'
Диагноз:
Очевидно, что в схеме базы (в "метаданных") поле есть. А в реальной таблице - нет.
То есть в новом релизе было добавлено поле, но так как не было реструктуризации - его нет в реальных таблицах.
Что делать:
Как ни странно, добавить недостающее поле :) Для этого нам нужно знать, в какую таблицу и какого типа.
В расследовании поможет профайлер (MS SQL Profiler).
Запускаем трассировку, воспроизводим ошибку, делаем поиск по имени поля, в идеале попадаем в запрос вида как на картинке.
Имя таблицы - в первой строке запроса, тип поля - параметр справа от самого поля.
В итоге у нас есть: куда и что добавить, и какого типа.
Добавим же это поле в SQL-студии, для этого нам поможет оператор ALTER TABLE ... ADD
После добавления поля в таблицу - во всех строках в этом поле будет значение NULL, что не годится, так как как правило вызывает ошибки преобразования типов (например в поле должно быть Булево, и есть строки кода
Если ЭтоДобавленноеПоле Тогда
или
РеквизитТипаБулево=ЭтоДобавленноеПоле
)
поэтому заполним сразу неким значением по-умолчанию
Я обычно заполнял единичкой (для ссылок, чисел и булево) либо пустой строкой '' для типа ntext
Пример скрипта
-- добавление в таблицу новой колонки
ALTER TABLE ИмяТаблицы ADD ИмяПоля ТипПоля NULL;
-- заполнение дефолтным значением
UPDATE ИмяТаблицы
SET ИмяПоля=ДефолтноеЗначение
При выполнении обращайте внимание на контекст выполнения, то есть в какой базе будет выполнен запрос. Для уверенности можно использовать явное указание через USE
USE target_base
GO
Выделяем нужный фрагмент, выполняем выделенный фрагмент текста запроса нажатием на Execute
Если всё ок - внизу отображается количество обработанных строк (цифры будут меняться в зависимости от реального количества строк в обрабатываемых таблицах)
Если всё сделали правильно - ошибка исчезнет.
Проблема №2. Наоборот, лишнее поле
Симптомы:
При попытке записать объект видим
Ошибка СУБД:
Microsoft OLE DB Provider for SQL Server: Cannot insert the value NULL into column '_Fld123', table 'SufferedBase.dbo._Document234'; column does not allow nulls. INSERT fails.
Напрямую не мешает, но косвенно жить не даёт :)
Дело в том, что многие поля на уровне SQL имеют ограничение NOT NULL. То есть NULL туда записать нельзя. И при записи 1С явно передаёт в SQL через INSERT какие поля и какими значениями заполнить.
И если в SQL есть поле, про которое 1С не знает - значит неявно получится попытка записать в это поле NULL. И будет следующая ошибка
Диагноз:
В новом релизе поле было удалено. В схеме базы (в "метаданных") поля уже нет. А в реальной таблице - осталось.
Что делать:
Решением будет удалить это поле из таблицы SQL.
С помощью конструкции
ALTER TABLE ИмяТаблицы DROP COLUMN ИмяПоля;
Ниже весь процесс (в красной рамке лишние поля, их нет в схеме базы, что видно в запущенной в 1С:Предприятии обработке, которая показывает структуру базы данных. Таких существует много, пользоваться можете любой, моя опубликована здесь )
Проблема №3. Количество полей в реальной таблице SQL отличается от количества полей в метаданных
Симптомы:
При попытке записать объект с заполненной табличной частью
Ошибка СУБД:
Microsoft OLE DB Provider for SQL Server: Column name or number of supplied values does not match table definition.
Диагноз:
Как и в прошлом случае, в схеме базы (в "метаданных") поля нет, в реальной таблице - осталось.
Разница с прошлой проблемой: расхождение в полях произошло в табличной части, а не в шапке.
Что делать:
Как и в прошлом случае, решением будет удалить это поле из таблицы SQL.
Но на этот раз - расследовать немного сложнее, так как нам неизвестен ни один идентификатор - ни проблемной таблицы, ни поля.
Как и раньше, ищем проблемный запрос профайлером.
посчитать реквизиты в запросе
Самое интересное здесь - имя таблицы, куда идёт вставка.
После чего обращаем пристальное внимание на поля этой таблицы, и сравниваем их с полями этой же таблицы, но той базы, которую использовали для лечения (живая база, откуда брали служебные таблицы Config и тд).
Для этого сравнения есть разные способы, самый эффективный на мой взгляд: получить скрипты создания этих таблиц (подробно способ описан в решении проблемы №4, ниже)
И сравнить их тексты, вот так:
Таким образом, видим в новой проблемной базе 2 лишних поля, удаляем их описанным ранее способом, и проблема решается. Если всё правильно расследовали и сделали, конечно :)
Вариация на тему
Был еще случай, когда ошибка та же, но в профайлере мне не удалось ничего по ней найти полезного.
Тогда по журналу регистрации увидел на каком документе остановилась транзакция загрузки данных (на этапе восстановления обмена РИБ), попробовал поменять данные в его табличных частях. Точней, увидел что есть пустая ТЧ, внес в нее новую строку, увидел что ошибка воспроизводится, и далее как на прошлом шаге - сравнил скрипты создания этой таблицы, увидел разницу в одном поле, удалил его из битой базы, стало хорошо.
Проблема №4. Нехватка целиком какой-то таблицы
Симптомы:
В разных транзакциях вот такое:
Ошибка СУБД:
Microsoft OLE DB Provider for SQL Server: Invalid object name ...
Диагноз:
В схеме базы (в "метаданных") таблица есть, а в базе - такая отсутствует.
В новом релизе таблицу добавили, но так как реструктуризации не было, в базе её нет.
Что делать:
Добавить.
Самое простое - добавить из живой базы
- Находим там эту таблицу
- Правый клик на ней
- Script Table As
- CREATE TO
- New Query...
- Меняем там имя целевой базы
- Выполняем
Радуемся, если проблема решались (опционально)
:)
Ещё кое-что
Был еще ряд проблем, которые не удалось классифицировать. Кратко о них:
- При реструктуризации исключение, жалоба на нехватку таблицы EDBT...
Как выяснилось, так кодируется таблица внешнего источника данных
После удаления этого внешнего источника данных из Конфигуратора - проблема решилась - Словил ошибку
Either the parameter @objname is ambiguous or the claimed @objtype (COLUMN) is wrong
после анализа удалось выяснить, что ошибка связана с агрегатами, после небольших экспериментов в Конфигураторе по удалению агрегатов - задача была решена
Если есть конфигурация поломанной базы (CF)...
, то можно восстановить методом проще. Раскрыть этот CF в пустую базу, и оттуда перетащить в битую базу таблицу Config
Вместо эпилога
Вопросы, конструктивную критику, пожелания, дополнения и предложения, как обычно в комментарии.
Если статья оказалась полезной/интересной - Вы знаете что делать :)
И еще.. Интересно ли кому-то легкий мануал по соответствию имён таблиц "SQL-1C" ?
Который позволит однозначно ответить на вопрос "А какой таблице 1С соответствует SQL-ная _SeqB567" и все аналогичные