Как определить, есть ли колонка в таблице или нет?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Определение наличия колонки в таблице
Это типичная задача при работе с СУБД напрямую или при динамическом формировании SQL запросов. Подходы зависят от СУБД и контекста.
1. PostgreSQL (основная СУБД 1С)
Способ 1: Information Schema (стандартный SQL)
SELECT EXISTS (
SELECT 1
FROM information_schema.columns
WHERE table_name = '_Reference123' -- Имя таблицы
AND column_name = 'Description' -- Имя колонки
AND table_schema = 'public'
);
Возвращает TRUE/FALSE — удобно в условиях и процедурах.
Способ 2: PostgreSQL системный каталог (быстрее)
SELECT EXISTS (
SELECT 1
FROM pg_attribute
JOIN pg_class ON pg_class.oid = pg_attribute.attrelid
WHERE pg_class.relname = '_Reference123'
AND pg_attribute.attname = 'Description'
AND pg_attribute.attnum > 0 -- Исключаем системные колонки
AND NOT pg_attribute.attisdropped
);
Данный метод быстрее, но менее переносим.
Способ 3: \d команда в psql
# Интерактивно в psql
\d _Reference123
# Вывелет все колонки таблицы
2. MS SQL Server
Information Schema:
IF EXISTS (
SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = '_Reference123'
AND COLUMN_NAME = 'Description'
)
BEGIN
PRINT 'Колонка существует';
END;
Системные представления:
IF COL_LENGTH('dbo._Reference123', 'Description') IS NOT NULL
BEGIN
PRINT 'Колонка существует';
END;
3. В коде 1С (высокоуровневый подход)
Использование объектной модели платформы:
// Для справочника
МетаОбъект = Метаданные.Справочники.Контрагенты;
КолонкаНайдена = Ложь;
Для Каждого Реквизит Из МетаОбъект.Реквизиты Цикл
Если Реквизит.Имя = "ИНН" Тогда
КолонкаНайдена = Истина;
Прерывание;
КонецЕсли;
КонецЦикла;
Если КолонкаНайдена Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Реквизит найден";
Сообщение.Сообщить();
КонецЕсли;
Этот способ безопаснее, работает независимо от версии СУБД.
Более универсальный подход через метаданные:
Процедура ПроверитьНаличиеРеквизита(МетаОбъект, ИмяРеквизита) Экспорт
Для Каждого Реквизит Из МетаОбъект.Реквизиты Цикл
Если Реквизит.Имя = ИмяРеквизита Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
// Проверяем табличные части
Для Каждого ТабЧасть Из МетаОбъект.ТабличныеЧасти Цикл
Если ТабЧасть.Имя = ИмяРеквизита Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецПроцедуры;
4. Динамический SQL в 1С
При использовании прямых запросов к СУБД:
Процедура ПроверитьКолонкуВПостгресе(ТаблицаИмя, КолонкаИмя) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| 1
|ИЗ
| information_schema.columns
|ГДЕ
| table_name = &ТаблицаИмя
| И column_name = &КолонкаИмя";
Запрос.УстановитьПараметр("ТаблицаИмя", НижРегистр(ТаблицаИмя));
Запрос.УстановитьПараметр("КолонкаИмя", НижРегистр(КолонкаИмя));
РезультатЗапроса = Запрос.Выполнить();
Возврат НЕ РезультатЗапроса.Пусто();
КонецПроцедуры;
5. Практический сценарий: миграция данных
Проверка при обновлении конфигурации:
Процедура ОбработатьСтарыеДанные() Экспорт
МетаОбъект = Метаданные.Справочники.Контрагенты;
// Проверяем наличие устаревшего реквизита
Если ПроверитьНаличиеРеквизита(МетаОбъект, "СтарыйФормат") Тогда
// Мигрируем данные
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Ссылка,
| СтарыйФормат
|ИЗ
| Справочник.Контрагенты";
ТаблицаДанных = Запрос.Выполнить().Выгрузить();
Для Каждого Строка Из ТаблицаДанных Цикл
Объект = Строка.Ссылка.ПолучитьОбъект();
Объект.НовыйФормат = ПреобразоватьСтарыеДанные(Строка.СтарыйФормат);
Объект.Записать();
КонецЦикла;
КонецЕсли;
КонецПроцедуры;
6. Оптимизация запроса
Неправильно (медленно):
-- Это попытается отобрать все данные и потом проверить
SELECT COUNT(*) FROM _Reference123;
Правильно (быстро):
-- Проверяем метаинформацию, не трогаем данные
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = '_Reference123' AND column_name = 'Description'
);
Рекомендации
- В 1С коде — используй метаданные (Метаданные.*), это безопаснее и переносимее
- Для прямого SQL — используй information_schema в PostgreSQL или COL_LENGTH в MS SQL
- В критичных операциях — проверяй наличие колонки перед USE, чтобы избежать ошибок
- Производительность — проверка метаинформации намного дешевле, чем SELECT данных
Вывод: Выбор метода зависит от контекста. В 1С коде — метаданные, в СУБД напрямую — information_schema. Всегда проверяй наличие перед использованием в динамических запросах.