Dans MS-SQL, comment puis-je INSÉRER dans une table temporaire et créer un champ IDENTITY sans déclarer d'abord la table temporaire?


36

J'ai besoin de sélectionner un tas de données dans une table temporaire pour ensuite faire quelques calculs secondaires; Pour que cela fonctionne mieux, j'aimerais avoir une colonne IDENTITY sur cette table. Je sais que je pourrais d'abord déclarer la table avec une identité, puis insérer le reste des données, mais y a-t-il un moyen de le faire en une étape?

+1

colonnes IDENTITY rendre les choses cohérentes pour plusieurs utilisateurs. PRIMARY KEY rend les choses efficaces. Utilisez les deux pour un effet maximum. 23 sept.. 082008-09-23 20:28:18

64

Oh vous de peu de foi:

SELECT *, IDENTITY(int) AS idcol 
    INTO #newtable 
    FROM oldtable 

http://msdn.microsoft.com/en-us/library/aa933208(SQL.80).aspx

  0

Ne fonctionne pas si oldtable a une colonne d'identité 23 sept.. 082008-09-23 20:38:39

+1

Mais bien sûr, vous ne pouvez pas en avoir deux. Il suffit de ne pas sélectionner le code d'identification dans la requête 23 sept.. 082008-09-23 20:54:24

  0

Vous devez faire attention si vous utilisez une clause ORDER BY et si vous attendez que "idcol" soit dans le même ordre. http://support.microsoft.com/kb/273586 04 oct.. 112011-10-04 18:28:36

  0

sélectionnez cast (CurrentID en tant qu'int) CurrentID que vous devriez aimer si oldtable a une colonne d'identité 05 févr.. 142014-02-05 17:58:29


-4

IIRC, la commande INSERT INTO utilise le schéma de la table source pour créer la table temporaire. Cela fait partie de la raison pour laquelle vous ne pouvez pas simplement créer une table avec une colonne supplémentaire. Les colonnes d'identité sont liées en interne à une construction SQL Server appelée générateur.


-3

Vous pouvez faire un Select Into, qui créerait la structure de la table à la volée en fonction des champs que vous sélectionnez, mais je ne pense qu'il va créer un champ d'identité pour vous.


1

Pour rendre les choses efficaces, vous devez faire déclarer que l'une des colonnes à une clé primaire:

ALTER TABLE #mytable 
ADD PRIMARY KEY(KeyColumn) 

Ce ne sera pas une variable pour le nom de la colonne.

Croyez-moi, vous êtes BEAUCOUP mieux de faire un: CREATE #myTable TABLE (ou éventuellement une table DECLARE @myTable), qui vous permet de définir IDENTITY et PRIMARY KEY directement.

  0

Cela dépend; les insertions dans une table indexée sont (avec quelques exceptions) plus lentes qu'une table non indexée en raison de la maintenance de l'arbre B +; cette application peut ne pas avoir suffisamment de données chargées dans la table temporaire pour rendre un index utile. Totalement dépend de la situation, et nous avons des informations insuffisantes pour savoir 23 sept.. 082008-09-23 20:58:20

  0

Il veut une "identité" pour "rendre les choses efficaces". Nous pouvons conclure qu'il aimerait accéder aux éléments par un identifiant qui n'existe pas déjà. Il est facile de trier par un identifiant qui n'existe pas déjà. 23 sept.. 082008-09-23 21:53:05

  0

il n'a pas défini efficace - ma pensée était qu'il voulait une identité pas pour la vitesse, mais pour la facilité d'utilisation. Mais si c'est une chose de performance, il suffit d'indexer l'une des colonnes existantes 23 sept.. 082008-09-23 23:19:48


5

Vous avez commenté: ne fonctionne pas si oldtable a une colonne d'identité.

Je pense que c'est votre réponse. Le #newtable obtient une colonne d'identité de la table oldtable automatiquement. Exécutez les instructions suivantes:

create table oldtable (id int not null identity(1,1), v varchar(10)) 

select * into #newtable from oldtable 

use tempdb 
GO 
sp_help #newtable 

Il vous montre que #newtable a la colonne d'identité.

Si vous ne voulez pas la colonne d'identité, essayer à la création de #newtable:

select id + 1 - 1 as nid, v, IDENTITY(int) as id into #newtable 
    from oldtable 

1

Bonne question & Matt était une bonne réponse.Pour développer la syntaxe un peu si le oldtable a une identité d'un utilisateur peut exécuter les éléments suivants:

SELECT col1, col2, IDENTITY(int) AS idcol 

    INTO #newtable 

    FROM oldtable 

-

Ce serait si le oldtable a été scénarisé quelque chose en tant que tel:

CREATE TABLE [dbo].[oldtable] 
(
    [oldtableID] [numeric](18, 0) IDENTITY(1,1) NOT NULL, 
    [col1] [nvarchar](50) NULL, 
    [col2] [numeric](18, 0) NULL, 
) 

Thx 4 l'information cette question m'a aidé,

Catto


2

Si vous voulez inclure la colonne qui est l'identité actuelle, vous pouvez toujours le faire mais vous devez explicitement lister les colonnes et transformer l'identité courante en int (en supposant qu'il en existe une maintenant), comme ceci:

select cast (CurrentID as int) as CurrentID, SomeOtherField, identity(int) as TempID 
into #temp 
from myserver.dbo.mytable 
  0

cela fonctionne pour moi. Merci 05 févr.. 142014-02-05 17:57:34


0

Si après le *, vous alias l'idcolumn qui rompt la requête une seconde fois ... et lui donne un nouveau nom ... il commence magiquement à fonctionner.

Select Identity (int) AS MATR_PROV, *, SectionID comme Fix2IDs dans #TempSections de Files_Sections