In MS-SQL, wie INSERT INTO in eine temporäre Tabelle und ein IDENTITY-Feld erstellt, ohne zuerst die temporäre Tabelle zu deklarieren?


36

Ich muss eine Reihe von Daten in eine temporäre Tabelle auswählen, um dann einige sekundäre Berechnungen durchzuführen; Damit es effizienter funktioniert, möchte ich eine IDENTITY-Spalte in dieser Tabelle haben. Ich weiß, dass ich die Tabelle zuerst mit einer Identität deklarieren und dann den Rest der Daten einfügen kann, aber gibt es eine Möglichkeit, es in einem Schritt zu tun?

+1

Identity-Spalten machen Dinge für mehrere Benutzer konsistent. PRIMARY KEY's machen die Dinge effizient. Verwenden Sie beide für maximale Wirkung. 23 sep. 082008-09-23 20:28:18

64

Oh ihr Kleingläubigen:

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

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

  0

Funktioniert nicht, wenn oldtable eine Identitätsspalte hat 23 sep. 082008-09-23 20:38:39

+1

Aber natürlich können Sie nicht zwei haben. Wählen Sie nicht die Ident-Spalte als Teil der Abfrage 23 sep. 082008-09-23 20:54:24

  0

Müssen Sie vorsichtig sein, wenn Sie eine ORDER BY-Klausel verwenden und erwarten, dass die "idcol" in der gleichen Reihenfolge sein. http://support.microsoft.com/kb/273586 04 okt. 112011-10-04 18:28:36

  0

wählen Sie Cast (CurrentID als int) als CurrentID Sie sollten dies, wenn oldtable eine Identitätsspalte hat 05 feb. 142014-02-05 17:58:29


-4

IIRC, der Befehl INSERT INTO verwendet das Schema der Quelltabelle, um die temporäre Tabelle zu erstellen. Das ist einer der Gründe, warum Sie nicht einfach versuchen können, eine Tabelle mit einer zusätzlichen Spalte zu erstellen. Identitätsspalten sind intern mit einem SQL Server-Konstrukt verknüpft, das als Generator bezeichnet wird.


-3

Sie könnten einen Select In tun, die die Tabellenstruktur im laufenden Betrieb auf die ausgewählten Felder basierend schaffen würde, aber ich weiß nicht denke, es wird ein Identitätsfeld für dich schaffen.


1

Um die Dinge effizienter zu machen, müssen Sie erklären zu tun, dass eine der Spalten ein Primärschlüssel zu sein:

ALTER TABLE #mytable 
ADD PRIMARY KEY(KeyColumn) 

, dass eine Variable für die Spaltennamen nicht stattfinden wird.

Vertrauen Sie mir, Sie sind viel besser dran a: CREATE #myTable TABLE (oder möglicherweise eine DECLARE TABLE @ myTable), mit denen Sie IDENTITY und PRIMARY KEY direkt festlegen können.

  0

Es hängt davon ab; Einfügungen in eine indizierte Tabelle sind (mit wenigen Ausnahmen) langsamer als eine nicht indizierte Tabelle aufgrund der B + Baumpflege; Diese App verfügt möglicherweise nicht über genügend Daten, die in die temporäre Tabelle geladen werden, damit sich ein Index lohnt. Völlig abhängig von der Situation, und wir haben nicht genügend Informationen, um zu wissen, 23 sep. 082008-09-23 20:58:20

  0

Er will eine "Identität", um Dinge effizient zu machen. Wir können daraus schließen, dass er gerne auf die Items mit einer ID zugreifen möchte, die es noch nicht gibt. Es ist einfach, nach einer ID zu sortieren, die noch nicht existiert. 23 sep. 082008-09-23 21:53:05

  0

hat er nicht effizient definiert - mein Denken war, dass er eine Identität nicht für die Geschwindigkeit, sondern für die Benutzerfreundlichkeit wollte. Aber wenn es eine Performance-Sache ist, indexieren Sie einfach eine der bestehenden Spalte 23 sep. 082008-09-23 23:19:48


5

Sie kommentierten: funktioniert nicht, wenn oldtable eine Identitätsspalte hat.

Ich denke, das ist deine Antwort. Die #newtable ruft automatisch eine Identitätsspalte aus der oldtable ab. Führen Sie die nächsten Anweisungen aus:

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

select * into #newtable from oldtable 

use tempdb 
GO 
sp_help #newtable 

Es zeigt Ihnen, dass #newtable die Identitätsspalte hat.

Wenn Sie nicht über die Identität Spalte wollen, versuchen Sie dies bei der Erstellung von #newtable:

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

1

Gute Frage & Matts war eine gute Antwort.ein wenig, wenn die OldTable eine Identität ein Benutzer über die Syntax zu erweitern hat könnte folgendes ausgeführt:

SELECT col1, col2, IDENTITY(int) AS idcol 

    INTO #newtable 

    FROM oldtable 

-

, dass, wenn die OldTable etwas als solche im Drehbuch wäre:

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

Thx 4 die Info diese Frage hat mir geholfen,

Catto


2

Wenn Sie die Spalte mit der aktuellen Identität einfügen möchten, können Sie dies dennoch tun. Sie müssen die Spalten jedoch explizit auflisten und die aktuelle Identität in ein int schreiben (vorausgesetzt, dass es sich um eins handelt):

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

das funktioniert für mich. Vielen Dank 05 feb. 142014-02-05 17:57:34


0

Wenn nach dem *, alias die IDcolumn, die die Abfrage ein zweites Mal bricht ... und geben Sie ihm einen neuen Namen ... es beginnt magisch zu arbeiten.

Select Identity (int) AS LFDNR, *, sectionid als Fix2IDs in #TempSections von Files_Sections