2010-10-01 15 views
271

Ottenuto una query SELECT complessa, dalla quale vorrei inserire tutte le righe in una variabile di tabella, ma T-SQL non lo consente.SELEZIONA INTA una variabile di tabella in T-SQL

Lungo le stesse linee, non è possibile utilizzare una variabile di tabella con le query SELECT INTO o INSERT EXEC. http://odetocode.com/Articles/365.aspx

Breve esempio:

declare @userData TABLE(
         name varchar(30) NOT NULL, 
         oldlocation varchar(30) NOT NULL 
         ) 

SELECT name, location 
INTO @userData 
FROM myTable 
    INNER JOIN otherTable ON ... 
WHERE age > 30 

I dati nella variabile di tabella verrebbe poi utilizzato per inserire/aggiornare nuovamente in tabelle diverse (per lo più copia degli stessi dati con aggiornamenti minori). L'obiettivo sarebbe semplicemente di rendere lo script un po 'più leggibile e più facilmente personalizzabile rispetto al fare lo SELECT INTO direttamente nelle tabelle giuste. Le prestazioni non sono un problema, poiché lo rowcount è piuttosto piccolo e viene eseguito manualmente solo quando necessario.
... o dimmi solo se sto sbagliando tutto.

risposta

423

provare qualcosa di simile:

DECLARE @userData TABLE(
    name varchar(30) NOT NULL, 
    oldlocation varchar(30) NOT NULL 
); 

INSERT INTO @userData (name, oldlocation) 
SELECT name, location FROM myTable 
INNER JOIN otherTable ON ... 
WHERE age > 30; 
+0

Se "SELEZIONA nome, posizione FROM myTable" come valori che inserirai nella tabella UserData, non importa se i nomi delle variabili nella select corrispondono ai nomi nella definizione della tabella. Stai selezionando 'name' per andare nella variabile 'name' del UserData, ma stai selezionando 'location' e in qualche modo assegnandolo alla variabile 'oldlocation' di UserData. SQL li mapperà automaticamente o genererà qualche tipo di eccezione? –

+0

Non importa il nome, solo il tipo di colonna. – CristiC

+3

Wow questo tipo di ha senso ma allo stesso tempo il parser in me si sente un po 'offeso :) –

6

Provare a usare INSERT invece di SELECT INTO:

INSERT @UserData 
SELECT name, location etc. 
12

Si potrebbe provare a utilizzare le tabelle temporanee ...

SELECT name, location INTO #userData FROM myTable 
INNER JOIN otherTable ON ... 
WHERE age>30 

È saltare l'impegno di dichiarare la tavola in quel modo ... Aiuta per query ad hoc ... Questo crea una tabella temporanea locale che non sarà visibile ad altre connessioni a meno che non si usi la stessa connessione attraverso la propria app.

se hai bisogno di variabili che possono essere dichiarati in questo modo:

DECLARE @userData TABLE(
    name varchar(30) NOT NULL, 
    oldlocation varchar(30) NOT NULL 
); 

INSERT INTO @userData 
SELECT name, location FROM myTable 
INNER JOIN otherTable ON ... 
WHERE age > 30; 
+2

Spiacente, ho dimenticato di menzionare che non ho i diritti per CREATE TABLE. – Indrek

+6

La creazione di una temperatura ha un po 'più di spese generali. – Paparazzi

+2

utilizzando la tabella temporanea non è sempre sicuro. Ad esempio, servizi web.Con i webservices con una singola connessione per limitare la connessione massima sul server E proteggere un po 'di più SQL, la tabella temporanea esiste per OGNI richiesta di passaggio e può sovrascrivere qualcuno che la sta usando. – Franck

77

Lo scopo di SELECT INTO è (per la documentazione, corsivo mio)

A creare una nuova tabella da valori in un'altra tabella

Ma hai già un tavolo di destinazione! Quindi, ciò che si vuole è

La dichiarazione INSERT aggiunge uno o più nuove righe a una tabella

È possibile specificare i valori dei dati nei seguenti modi :

...

Utilizzando una sottoquery SELECT per specificare i valori dei dati per una o più righe, come ad esempio:

INSERT INTO MyTable 
(PriKey, Description) 
     SELECT ForeignKey, Description 
     FROM SomeView 

E in questa sintassi, è consentito per MyTable di essere una variabile di tabella .

+0

Grazie per la spiegazione! – Indrek

+0

Vorrei davvero che la risposta accettata includesse queste informazioni! –

+0

I get MyTable è "Nome oggetto non valido", quindi manca questa risposta. –

-4

Uno dei motivi per utilizzare SELECT INTO è che consente di utilizzare IDENTITÀ:

SELECT IDENTITY(INT,1,1) AS Id, name 
INTO #MyTable 
FROM (SELECT name FROM AnotherTable) AS t 

Questo non avrebbe funzionato con una variabile di tabella, che è troppo male ...

+5

Tuttavia, è possibile dichiarare una variabile di tabella con una colonna 'IDENTITY'. –

4

Innanzitutto creare una temperatura tabella:

Fase 1:

create table #tblOm_Temp (

    Name varchar(100), 
    Age Int , 
    RollNumber bigint 
) 

** Passaggio 2: ** Inserisci un valore nella tabella Temp.

insert into #tblom_temp values('Om Pandey',102,1347) 

Fase 3: dichiarare una variabile di tabella per contenere i dati della tabella Temp.

declare @tblOm_Variable table(

    Name Varchar(100), 
    Age int, 
    RollNumber bigint 
) 

Fase 4: selezionare il valore da tabella temporanea e inserire nella variabile di tabella.

insert into @tblOm_Variable select * from #tblom_temp 

valore Infine viene inserito da una tabella temporanea alla tabella variabile

Fase 5: può controllare il valore inserito nella variabile di tabella.

select * from @tblOm_Variable 
13

È anche possibile utilizzare le espressioni di tabella comuni per archiviare i dataset temporanei. Essi sono più elegante e accogliente ad hoc:

WITH userData (name, oldlocation) 
AS 
(
    SELECT name, location 
    FROM myTable INNER JOIN 
     otherTable ON ... 
    WHERE age>30 
) 
SELECT * 
FROM userData -- you can also reuse the recordset in subqueries and joins 
+0

Love this! Grazie. – fourpastmidnight

0

OK, ora con abbastanza sforzo sono in grado di inserire nel @Table utilizzando il seguito:

INSERT @TempWithheldTable SELEZIONA
a.SuspendedReason, a.SuspendedNotes, a.SuspendedBy, a.ReasonCode FROM OPENROWSET (BULK 'C: \ Databases \ WithHeld.csv', FORMATFILE = N'C: \ Databases \ Format.txt',
FILEERRORI = N'C : \ Te mp \ MovieLensRatings.txt ' ) AS a;

La cosa principale qui è selezionare le colonne da inserire.

Problemi correlati