Явное значение для столбца идентификаторов в таблице можно указывать только в том случае, если используется список столбцов, а для IDENTITY_INSERT задано значение ON SQL Server. - PullRequest
167 голосов
/ 05 января 2010

Я пытаюсь сделать этот запрос

INSERT INTO dbo.tbl_A_archive
  SELECT *
  FROM SERVER0031.DB.dbo.tbl_A

но даже после того, как я побежал

set identity_insert dbo.tbl_A_archive on

Я получаю это сообщение об ошибке

Явное значение для столбца идентификаторов в таблице 'dbo.tbl_A_archive' можно указывать только в том случае, если используется список столбцов и IDENTITY_INSERT установлен в ON.

tbl_A - это огромная таблица в строках и ширине, то есть в ней МНОГО столбцов. Я не хочу печатать все столбцы вручную. Как я могу заставить это работать?

Ответы [ 12 ]

290 голосов
/ 23 августа 2012
SET IDENTITY_INSERT tableA ON

Вы должны составить список столбцов для оператора INSERT:

INSERT Into tableA ([id], [c2], [c3], [c4], [c5] ) 
SELECT [id], [c2], [c3], [c4], [c5] FROM tableB

не похоже на «Вставить в таблицу A ВЫБРАТЬ ........»

SET IDENTITY_INSERT tableA OFF
66 голосов
/ 05 января 2010

Ну, сообщение об ошибке в основном говорит обо всем. У вас есть следующие варианты:

  • Составьте список столбцов (ВЫБЕРИТЕ на INFORMATION_SCHEMA.COLUMNS и хороший текстовый редактор или решения, предложенные Андомаром и Дейвом, могут помочь вам в этом)

OR

  • сделать столбец идентификаторов в tbl_A_archive обычным (не идентифицирующим) столбцом int (поскольку это архивная таблица, зачем вам столбец идентификаторов?).
35 голосов
/ 05 января 2010

Если вы используете SQL Server Management Studio, вам не нужно вводить список столбцов самостоятельно - просто щелкните правой кнопкой мыши таблицу в Object Explorer и выберите Таблица сценариев как -> ВЫБРАТЬ на -> Новое окно редактора запросов .

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

SELECT SUBSTRING(
    (SELECT ', ' + QUOTENAME(COLUMN_NAME)
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_NAME = 'tbl_A'
        ORDER BY ORDINAL_POSITION
        FOR XML path('')),
    3,
    200000);
18 голосов
/ 05 января 2010

Согласен с ответом Хайнци. Для первого второго варианта, вот запрос, который генерирует разделенный запятыми список столбцов в таблице:

select name + ', ' as [text()] 
from sys.columns 
where object_id = object_id('YourTable') 
for xml path('')

Для больших таблиц это может сэкономить много печатной работы:)

10 голосов
/ 05 января 2010

Если «архивная» таблица должна быть точной копией вашей основной таблицы, я бы просто предложил вам удалить тот факт, что id является столбцом идентификаторов. Таким образом, вы сможете вставить их.

В качестве альтернативы вы можете разрешить и запретить вставку идентификаторов для таблицы с помощью следующего оператора

SET IDENTITY_INSERT tbl_A_archive ON
--Your inserts here
SET IDENTITY_INSERT tbl_A_archive OFF

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

sp_columns tbl_A_archive 

Это вернет вам все столбцы из таблицы, которые вы затем сможете вырезать и вставить в свой запрос. (Это почти ВСЕГДА лучше, чем использование *)

6 голосов
/ 16 декабря 2017

Для оператора SQL также необходимо указать список столбцов. Например,

INSERT INTO tbl (idcol1,col2) VALUES ( value1,value2)

вместо

INSERT INTO tbl VALUES ( value1,value2)
3 голосов
/ 31 марта 2016

Чтобы заполнить все имена столбцов в списке, разделенном запятыми, для оператора Select для решений, упомянутых для этого вопроса, я использую следующие параметры, поскольку они немного менее многословны, чем в Andomar. Андромар по-прежнему вполне приемлемо, однако.

1)

SELECT column_name + ',' 
FROM   information_schema.columns 
WHERE  table_name = 'YourTable'

2) Это, вероятно, самый простой подход к созданию столбцов, если у вас есть SQL Server SSMS.

1) Перейдите к таблице в обозревателе объектов и нажмите + слева от имени таблицы или дважды щелкните имя таблицы, чтобы открыть подсписок.

2) Перетащите подпапку столбца в основную область запроса, и он автоматически вставит весь список столбцов.

2 голосов
/ 14 сентября 2018

Это должно работать. Я только что столкнулся с вашей проблемой:

SET IDENTITY_INSERT dbo.tbl_A_archive ON;
INSERT INTO     dbo.tbl_A_archive (IdColumn,OtherColumn1,OtherColumn2,...)
SELECT  *
FROM        SERVER0031.DB.dbo.tbl_A;
SET IDENTITY_INSERT dbo.tbl_A_archive OFF;

К сожалению, вам, кажется, нужен список столбцов, включая столбец идентификаторов, чтобы вставить записи, в которых указан идентификатор. Однако , вам не нужно перечислять столбцы в SELECT. Как @ Dave Cluderay предположил, что это приведет к тому, что вы сможете скопировать и вставить отформатированный список (если меньше 200000 символов).

Я добавил ИСПОЛЬЗОВАНИЕ, так как переключаюсь между экземплярами.

USE PES
SELECT SUBSTRING(
    (SELECT ', ' + QUOTENAME(COLUMN_NAME)
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_NAME = 'Provider'
        ORDER BY ORDINAL_POSITION
        FOR XML path('')),
    3,
    200000);
2 голосов
/ 30 марта 2016

Оба будут работать, но если вы все равно получите ошибку, используя # 1, тогда перейдите к # 2

1)

SET IDENTITY_INSERT customers ON
GO
insert into dbo.tbl_A_archive(id, ...)
SELECT Id, ...
FROM SERVER0031.DB.dbo.tbl_A

2)

SET IDENTITY_INSERT customers ON
GO
insert into dbo.tbl_A_archive(id, ...)
VALUES(@Id,....)
1 голос
/ 08 сентября 2017

Вам необходимо указать имя столбца, который вы хотите вставить, если есть столбец Identity. Таким образом, команда будет выглядеть так:

SET IDENTITY_INSERT DuplicateTable ON

INSERT Into DuplicateTable ([IdentityColumn], [Column2], [Column3], [Column4] ) 
SELECT [IdentityColumn], [Column2], [Column3], [Column4] FROM MainTable

SET IDENTITY_INSERT DuplicateTable OFF

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

SELECT column_name + ','
FROM   information_schema.columns 
WHERE  table_name = 'TableName'
for xml path('')

(после удаления последней запятой (',')) Просто скопируйте имя последнего столбца.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...