Priya-Kiko Ответов: 3

Как вставить в таблицу из инструкции Select для столбца идентификаторов присутствует


Привет,

У нас есть SQL-таблица "attendmast". В конце каждого месяца нам нужно добавлять данные из этой таблицы в другую таблицу "attendmastm". Обе таблицы имеют одинаковый набор столбцов. Для этого мы используем следующую команду :
insert into attendmastm select * from attendmast

Это возвращает ошибку
An explicit value for the identity column in table 'attendmastm' can only be specified when a column list is used and IDENTITY_INSERT is ON.

Мы понимаем, что "select *" не является хорошей практикой кодирования... но в этом случае мы не можем указать столбцы, так как программно мы получаем имя таблицы, и эта операция должна быть выполнена над этой таблицей.

Пожалуйста, предложите любой выход. Заранее спасибо.

Что я уже пробовал:

Попробовал погуглить. Нашел несколько ссылок, говорящих об этом. Но это не совсем то, чего мы хотим.

PIEBALDconsult

attendmastm не должен иметь идентичности.

3 Ответов

Рейтинг:
5

Mahesh Pratap Singh

Поскольку вы получаете имя таблицы прагматично, вы также можете получить имя столбцов этой таблицы, используя следующий запрос:

SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS where table_schema='dbo' and TABLE_NAME = 'attendmast'


Объедините все столбцы в строку, разделенную запятыми, и используйте в качестве оператора select.

Это может вам помочь.


Рейтинг:
27

Wendelius

Если вы хотите, чтобы значение ключа менялось при копировании данных из исходной таблицы в целевую, то Решение 1 будет правильным.

Однако, поскольку вы описываете, что хотите добавить данные, я могу себе представить, что значение ключа должно быть таким же в целевой таблице, как и в исходной. Если это так, то вы можете использовать оператор SET IDENTITY_INSERT, чтобы определить значение ключевого столбца независимо от того, является ли он идентификатором. Взгляните на SET IDENTITY_INSERT (Transact-SQL) | Microsoft Docs[^]

Но если это так, то вы должны рассмотреть две вещи:
- Почему целевая таблица содержит столбец идентификаторов, если все данные однозначно идентифицированы в исходной таблице.
- Копирование данных в таблицу из другой таблицы ежемесячно звучит так, как будто вы пытаетесь решить какую-то другую проблему, возможно, связанную с производительностью. Если это так, то я считаю, что это может быть не самый лучший вариант. Перемещение данных часто создает ненужную сложность, в то время как исходная проблема-производительность-может быть решена с помощью других решений.


Priya-Kiko

Спасибо за ответ.

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

Во-первых, месячная таблица может отсутствовать. Поэтому мы используем :

если уже присутствует в sys. tables
вставить в &ЛТ;monthtable и GT; выбрать * из &ЛТ;daytable&ГТ;;
еще
выберите * в < monthtable> Из & lt;daytable> ;

удалить из & lt;daytable>

Эта операция выполняется в конце дня как часть "процесса закрытия дня".

Для наших операций решение 2, по-видимому, является единственным выходом.

Wendelius

Я так понимаю, что вы убираете ежедневные столы из соображений производительности. Если это так, то я вроде как понимаю.

Однако трудно понять, почему каждый месяц нуждается в собственной таблице истории? Насколько я вижу, это добавляет дополнительную сложность, потому что вы не можете использовать фиксированные имена таблиц и так далее.

Вы написали, что ежемесячные таблицы используются для отчетности. Что произойдет, если вы захотите делать отчетность не ежемесячно, а ежеквартально, еженедельно или даже с динамическим диапазоном дат? С этим может стать очень трудно справиться.

Я бы предложил проанализировать различные варианты. Если вам действительно нужно хранить ежедневные данные в отдельной таблице, это нормально, но вы должны, по крайней мере, рассмотреть возможность наличия только одной таблицы истории.

Если основная проблема заключается в производительности, помните, что план индексации не обязательно должен быть таким же для таблицы истории, как и для ежедневной таблицы. Например, вы можете иметь совершенно разные индексы в ежедневной таблице для поддержки быстрых операций OLTP, в то время как таблица истории может иметь различные типы индексов для поддержки отчетов.

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

Mahesh Pratap Singh

Если вы считаете решение 2 ответом,пожалуйста, отметьте его.

Рейтинг:
1

OriginalGriff

Поскольку таблицы всегда имеют одни и те же столбцы, просто перечислите столбцы на обоих:

INSET INTO attendmatsm (col2, col3) SELECT col2, col3 FROM attendmast
Поскольку таблицы имеют один и тот же столбец, все они должны иметь одно и то же имя, независимо от имени таблицы.
Если они этого не сделают, то, скорее всего, определение таблицы будет неправильным, и вы будете вставлять плохие данные в свою главную таблицу.

Но это действительно выглядит как плохой дизайн - я не уверен точно, что вы пытаетесь сделать с данными, но есть вероятность, что ваша структура хранения ошибочна.


Priya-Kiko

Спасибо за ответ.

Данные в исходной таблице(таблицах) будут использоваться в повседневных расчетных транзакциях, в то время как данные в целевой таблице(таблицах) будут доступны не так часто.

Поэтому мы приняли эту логику, чтобы использовать файлы месяцев для отчетных операций и очищать данные в таблицах дней в начале дня и использовать их в транзакциях. Эта операция переноса данных из таблицы дней в таблицу месяцев происходит изо дня в день.

Кроме того, мы не можем указать имена столбцов, так как эта операция выполняется для многих таблиц, и наша функция получает имя таблицы в качестве параметра.