J'essaie de faire cette requête
INSERT INTO dbo.tbl_A_archive
SELECT *
FROM SERVER0031.DB.dbo.tbl_A
mais même après avoir couru
set identity_insert dbo.tbl_A_archive on
Je reçois ce message d'erreur
Une valeur explicite pour la colonne d'identité de la table 'dbo.tbl_A_archive' ne peut être spécifiée que lorsqu'une liste de colonnes est utilisée et que IDENTITY_INSERT est activé.
tbl_A
est une table énorme en lignes et en largeur, c’est-à-dire qu’elle contient BEAUCOUP de colonnes. Je ne veux pas avoir à taper toutes les colonnes manuellement. Comment puis-je obtenir que cela fonctionne?
Eh bien, le message d'erreur dit tout. Vous avez les options suivantes:
OR
tbl_A_archive
une colonne int régulière (non-identité) (puisqu'il s'agit d'une table d'archivage, pourquoi avez-vous besoin d'une colonne d'identité?).SET IDENTITY_INSERT tableA ON
Vous devez créer une liste de colonnes pour votre instruction INSERT:
INSERT Into tableA ([id], [c2], [c3], [c4], [c5] )
SELECT [id], [c2], [c3], [c4], [c5] FROM tableB
pas comme "INSERER dans la tableA SELECT ........"
SET IDENTITY_INSERT tableA OFF
Si vous utilisez SQL Server Management Studio, vous n'avez pas besoin de taper la liste des colonnes vous-même. Cliquez avec le bouton droit de la souris sur la table dans Object Explorer et choisissez Script Table comme -> SELECT pour -> Nouvelle fenêtre de l'éditeur de requête .
Si ce n'est pas le cas, une requête semblable à celle-ci devrait vous aider comme point de départ:
SELECT SUBSTRING(
(SELECT ', ' + QUOTENAME(COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'tbl_A'
ORDER BY ORDINAL_POSITION
FOR XML path('')),
3,
200000);
D'accord avec la réponse de Heinzi. Pour la seconde option, voici une requête qui génère une liste de colonnes séparées par une virgule dans une table:
select name + ', ' as [text()]
from sys.columns
where object_id = object_id('YourTable')
for xml path('')
Pour les grandes tables, cela peut économiser beaucoup de travail de frappe :)
Si la table "archive" est censée être une copie exacte de votre table principale, je vous suggère simplement de supprimer le fait que l'identifiant est une colonne identiy De cette façon, vous pourrez les insérer.
Sinon, vous pouvez autoriser et interdire les insertions d'identité pour la table avec l'instruction suivante.
SET IDENTITY_INSERT tbl_A_archive ON
--Your inserts here
SET IDENTITY_INSERT tbl_A_archive OFF
Enfin, si vous avez besoin que la colonne d’identité fonctionne telle quelle, vous pouvez toujours exécuter le proc stocké.
sp_columns tbl_A_archive
Cela vous retournera toutes les colonnes de la table que vous pourrez ensuite couper et coller dans votre requête. (C'est presque TOUJOURS mieux que d'utiliser un *)
Pour l'instruction SQL, vous devez également spécifier la liste des colonnes. Pour par exemple.
INSERT INTO tbl (idcol1,col2) VALUES ( value1,value2)
au lieu de
INSERT INTO tbl VALUES ( value1,value2)
Afin de renseigner tous les noms de colonne dans une liste délimitée par des virgules pour une instruction Select des solutions mentionnées pour cette question, j'utilise les options suivantes, car elles sont un peu moins explicites que celles d'Andomar. Andomar est toujours parfaitement acceptable.
1)
SELECT column_name + ','
FROM information_schema.columns
WHERE table_name = 'YourTable'
2) Il s'agit probablement de l'approche la plus simple pour créer des colonnes, Si vous avez SQL Server SSMS.
1) Accédez à la table dans l'Explorateur d'objets et cliquez sur le signe + situé à gauche du nom de la table ou double-cliquez sur le nom de la table pour ouvrir la liste secondaire.
2) Faites glisser le sous-dossier de colonne sur la zone de requête principale et la copie automatique de la liste complète des colonnes sera automatiquement effectuée.
Les deux fonctionneront, mais si vous avez toujours Si vous obtenez une erreur en utilisant # 1 alors allez pour # 2
SET IDENTITY_INSERT customers ON
GO
insert into dbo.tbl_A_archive(id, ...)
SELECT Id, ...
FROM SERVER0031.DB.dbo.tbl_A
SET IDENTITY_INSERT customers ON
GO
insert into dbo.tbl_A_archive(id, ...)
VALUES(@Id,....)
Bonne journée.
Cela devrait marcher. Je viens de rencontrer votre problème:
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;
Malheureusement, il semble que vous ayez besoin d'une liste des colonnes, y compris la colonne identité, pour insérer des enregistrements spécifiant l'identité. Cependant , vous n'avez PAS à lister les colonnes du SELECT . Comme @ Dave Cluderay l'a suggéré, cela donnera une liste formatée que vous pourrez copier et coller (si moins de 200000 caractères ).
J'ai ajouté le USE depuis que je bascule entre les instances.
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);
Vous devez spécifier le nom de colonne que vous souhaitez insérer s'il existe une colonne Identity. Ainsi, la commande sera comme ci-dessous:
SET IDENTITY_INSERT DuplicateTable ON
INSERT Into DuplicateTable ([IdentityColumn], [Column2], [Column3], [Column4] )
SELECT [IdentityColumn], [Column2], [Column3], [Column4] FROM MainTable
SET IDENTITY_INSERT DuplicateTable OFF
Si votre table a plusieurs colonnes, obtenez le nom de ces colonnes en utilisant cette commande.
SELECT column_name + ','
FROM information_schema.columns
WHERE table_name = 'TableName'
for xml path('')
(après avoir supprimé la dernière virgule (',')) Copiez simplement le nom des colonnes précédentes.
Cette image montre comment insérer dans une table lorsque la colonne de clé primaire d'identité est activée. [] [Insérer dans le tableau lorsque la colonne de clé primaire d’identité]
Car si vous souhaitez insérer vos valeurs d'une table à une autre via une procédure stockée. J'ai utilisé this et this , ce dernier est presque comme la réponse d'Andomar.
CREATE procedure [dbo].[RealTableMergeFromTemp]
with execute as owner
AS
BEGIN
BEGIN TRANSACTION RealTableDataMerge
SET XACT_ABORT ON
DECLARE @columnNameList nvarchar(MAX) =
STUFF((select ',' + a.name
from sys.all_columns a
join sys.tables t on a.object_id = t.object_id
where t.object_id = object_id('[dbo].[RealTable]')
order by a.column_id
for xml path ('')
),1,1,'')
DECLARE @SQLCMD nvarchar(MAX) =N'INSERT INTO [dbo].[RealTable] (' + @columnNameList + N') SELECT * FROM [#Temp]'
SET IDENTITY_INSERT [dbo].[RealTable] ON;
exec(@sqlcmd)
SET IDENTITY_INSERT [dbo].[RealTable] OFF
COMMIT TRANSACTION RealTableDataMerge
END
GO