ДИСКЛЕЙМЕР
Автор не несет никакой ответственности, кроме как за достоверность предоставленной информации.
Всю нижеследующую информацию воспринимать и использовать на свой страх и риск.
После вступительной части была получена база, которая нормально открывалась (как в конфигураторе, так и в режиме предприятия), аварийное завершение с записью дампа спровоцировать не получалось — это уже было намного лучше, чем первоначальное состояние.
Но и работать с базой было нельзя. Открытие формы констант, определенных документов, попытка обновить конфигурацию ИБ и другие обычные действия — давали исключения уровня СУБД с добровольно-принудительным предложением завершить работу 🙂 Читайте ниже о том, как я победил каждое из них.
Примеры ошибок и приёмы лечения
Проблема №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» и все аналогичные
предлагаю автору перейти от эмпирического поиска ошибок к аналитическому.
разобраться , как 1с8 сопоставляет реквизиты и поля бд.
Для этого научиться парсить запись dbnames таблицы params , записи таблицы config.
по их данным строить сопоставления имен метаданных и имен таблиц и полей.
подсказка: 1с хранит описания метаданных в виде текста в кодировке utf8 (сжатого deflate)
tsql не умеет работать с utf . а xml умеет. н уи про BOM не забываем.
(1) МихаилМ, учитывая Ваш совет — что конкретно можно было сделать лучше в рамках данной статьи?
А так, согласен, как ра3 собирался распарсить эти таблицы, посмотреть что внутри? Приходилось ли Вам МЕНЯТЬ содержимое этих таблиц (deflate-и3менение-inflate-3апись в ба3у)?
+1. Сложная и нужная тема
А подобные комментарии: (1)
«разобраться , как 1с8 сопоставляет реквизиты и поля бд. «, — уменьшаю неопределенность и говорят куда копать.
(2) приходилось изменять dbnames. читайте мой комментарий к Вашей первой части про восстановление.
(4) МихаилМ, попробовал… Честно говоря, не понял как Вы меняли DBNames..
http://infostart.ru/public/74406/ Deflate и чтение только делается
Ведь в указанной разработке
Inflate и запись — непонятно как…
Но Бог с ним, у меня даже на чтение не получается… (((
Тестовый скрипт Test.sql возвращает пустую таблицу.
Скрипт
SELECT * FROM [mybase].[dbo].[fn_GetBinary] (
(Select TOP 1 BinaryData From Config)) k
также возвращает пустую таблицу… 🙁
Возможно неправильно подключил?
Скрипты подключения во вложении (один вспомогательный просто разрешает выполнение CLR)
Можете подсказать, где я ошибся, и как всё-таки прочитать двоичные данные из SQL?
(5) сейчас нет доступа к наработкам. поэтому ничем помочь не могу тк не помню . на инфостарте есть несколько аналогичных clr + исходники на си шапр.
Например
попробуйте другую.
(6) МихаилМ, спасибо! поискать по маске CLR я что-то не догадался.. Буду пробовать!
Как выяснилось, почти все эти проблемы решаются путем добавления реквизита, в конфигураторе, к объекту метаданных на который ругается система.
Таблица красиво пересоздается.
(8) «Все эти проблемы» совершенно точно не может решить добавление реквизита. Так как в некоторых случаях реквизит УЖЕ лишний (в таблице SQL есть, а описании метаданных — нет). Его надо удалять. И через конфигуратор этого не сделать, так как конфигуратор об этом ничего не «знает». В этом и проблема.
Возможно, у вас был сбой какого-то другого рода.
Более детально Ваш случай развернуть можете?
Который позволит однозначно ответить на вопрос «А какой таблице 1С соответствует SQL-ная _SeqB567» и все аналогичные
а можно мануал?
(10)https://infostart.ru/bitrix/components/infostart/forum.interface/show_file.php?fid=864409&action=download
(11)ого) спасибо
(9) Фишка в другом, когда добавляется реквизит, 1с реструктуризирует объект, и делает это правильно.
Там не важно были лишние, или чего то нехватало, 1С воссоздаст все как нужно.
(13) Не знаю, какой кейс у вас был, но повторюсь, база мне на восстановление досталась в следующем состоянии
То есть, очевидно, проблема другого характера.
UPD При борьбе с ошибкой
поиск по маске object’
«Either the parameter @objname is ambiguous or the claimed @objtype (COLUMN) is wrong»
поможет следующая стратегия
1. Включить профайлер на мониторинг
2. Спровоцировать ошибку
3. Остановить сбор логов в профайлере
4. Запустить
5. Обнаружится запрос вида
declare @p1 int
set @p1=1424
declare @p4 int
set @p4=1
exec sp_prepexec @p1 output,N’@P1 int OUTPUT’,N’EXEC @P1 = sp_rename N»[dbo].[_AccumRgAggOpt10310]», N»_AccumRgAggOpt10310OG», N»object»
‘,@p4 output
select @p1, @p4
В котором _AccumRgAggOpt10310 — недостающая таблица, изза которой возникает ошибка.
То есть при обновлении конфигуратор ожидает наличие этой таблицы, пытается её переименовать вот таким скриптом, но SQL её не находит, и возникает исключение.
Решением будет добавить эту таблицу вручную в SQL.
В моём случае это был скрипт на создание из аналогичной таблицы (через SCRIPT CRE ATE TABLE)
Точнее больше 50 таблиц
В итоге скрипт получил обработкой
Если интересует подробности — пишите сюда или в личку, поделюсь опытом!