SQL Server SELECT INTO @variable?


250

Ho il seguente codice in uno dei miei Procs archiviati Sql (2008) che funziona perfettamente:

    CREATE PROCEDURE [dbo].[Item_AddItem]
        @CustomerId uniqueidentifier,
        @Description nvarchar(100),
        @Type int,
        @Username nvarchar(100),
    AS
    BEGIN

        DECLARE @TopRelatedItemId uniqueidentifier;
        SET @TopRelatedItemId = 
        (
           SELECT top(1) RelatedItemId 
           FROM RelatedItems 
           WHERE CustomerId = @CustomerId
        ) 

        DECLARE @TempItem TABLE
        (
            ItemId uniqueidentifier,
            CustomerId uniqueidentifier,
            Description nvarchar(100),
            Type int,
            Username nvarchar(100),
            TimeStamp datetime
        );

        INSERT INTO Item
        OUTPUT INSERTED.* INTO @TempItem
        SELECT NEWID(), @CustomerId, @Description, @Type, @Username, GETDATE()

        SELECT
            ItemId,
            CustomerId,
            @TopRelatedItemId,
            Description,
            Type,
            Username,
            TimeStamp
        FROM
            @TempItem
END
GO

Quindi la domanda per voi ragazzi è che c'è la possibilità di fare qualcosa del genere:

DECLARE @TempCustomer TABLE
(
   CustomerId uniqueidentifier,
   FirstName nvarchar(100),
   LastName nvarchar(100),
   Email nvarchar(100)
);
SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
INTO 
    @TempCustomer 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

In modo da poter riutilizzare questi dati dalla memoria in altre dichiarazioni seguenti? SQL Server si adatta perfettamente con l'istruzione precedente, tuttavia non voglio creare variabili separate e inizializzare ognuna di esse tramite un'istruzione SELECT separata sulla stessa tabella .... UGH !!!

Qualche suggerimento su come ottenere qualcosa sulla falsariga senza più domande sullo stesso tavolo?


1
"per creare variabili separate e inizializzare ognuna di esse tramite un'istruzione SELECT separata" - perché dovresti farlo? declare @t tableuna volta, e se hai bisogno di riutilizzarlo, spara a DELETE @TempCustomerprima di reinserirlo
RichardTheKiwi

Risposte:


204

Non è possibile SELEZIONARE .. INTO .. ​​una TABELLA VARIABILE. Il meglio che puoi fare è crearlo prima, quindi inserirlo in esso. Il tuo secondo frammento deve essere

DECLARE @TempCustomer TABLE
(
   CustomerId uniqueidentifier,
   FirstName nvarchar(100),
   LastName nvarchar(100),
   Email nvarchar(100)
);
INSERT INTO 
    @TempCustomer 
SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

5
Va notato che questo funziona bene anche in un contesto CTE. Bazinga!
Michael Krauklis,

4
Qualcuno ha una risposta sul perché non è possibile selezionare una variabile di tabella come è possibile con una tabella temporanea effettiva?
KSwift87

504

Se desideri semplicemente assegnare alcune variabili per un uso successivo, puoi eseguirle in un colpo solo con qualcosa lungo queste linee:

declare @var1 int,@var2 int,@var3 int;

select 
    @var1 = field1,
    @var2 = field2,
    @var3 = field3
from
    table
where
    condition

Se questo è il tipo di cosa che stai cercando


1
La migliore risposta è imho, ma cosa succede se i risultati sono più di uno?
capitano666,

Se i risultati sono più di uno, otterrai uno dei valori disponibili. Ciò potrebbe costituire un puzzle interessante! Vedi mssqltips.com/sqlservertip/1888/…
Smandoli

8
Per forzare la query a restituire una singola riga, utilizzare SELEZIONA TOP 1
Adrian l'

1
@Adrian Sì, la query sopra presuppone che tu abbia selezionato una singola riga. È inoltre possibile utilizzare le funzioni di ordinamento e aggregazione se si desidera una logica più elaborata.
dougajmcdonald,

1
Nel caso in cui non si stia utilizzando il tipo di database utilizzato dall'OP, non tutti supportano TOP 1 come menzionato da Adrian. SQL Server / MS Access utilizzano TOP, MySQL utilizza LIMIT e Oracle utilizza ROWNUM. Vedere w3schools.com/sql/sql_top.asp per ulteriori informazioni.
Tyler,

33

Puoi farlo:

SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email
INTO #tempCustomer 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

poi più tardi

SELECT CustomerId FROM #tempCustomer

non è necessario dichiarare la struttura di #tempCustomer


3
@webturner Nessuno di questi punti è vero. Le tabelle temporanee non sono incluse al di fuori del proc e le variabili della tabella non sono più "solo memoria" delle tabelle temporanee.
Martin Smith,

7
Non dimenticare di aggiungere un DROP TABLE #tempCustomerquando #tempCustomernon è più necessario altrimenti la selezione successiva provocherà un #tempCustomer already existserrore
ViRuSTriNiTy

15

Sembra che la tua sintassi sia leggermente fuori. Questo ha alcuni buoni esempi

DECLARE @TempCustomer TABLE
(
   CustomerId uniqueidentifier,
   FirstName nvarchar(100),
   LastName nvarchar(100),
   Email nvarchar(100)
);
INSERT @TempCustomer 
SELECT 
    CustomerId, 
    FirstName, 
    LastName, 
    Email 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId

Poi più tardi

SELECT CustomerId FROM @TempCustomer

2

Sembra che tu voglia tabelle temporanee. http://www.sqlteam.com/article/temporary-tables

Nota che #TempTable è disponibile in tutto il tuo SP.

Nota che ## TempTable è disponibile per tutti.


2
## temptable - fino a quando il proprietario (creatore) non lo cancella o viene disconnesso
RichardTheKiwi

4
Non voglio tabelle temporanee. Le tabelle temporanee sono costose e lente. Voglio solo conservare un po 'di dati per un record specifico per un breve periodo di tempo e renderli disponibili a più istruzioni sql, senza ricerche successive. Dato che le variabili di tabella hanno un ambito all'interno del proc memorizzato in cui sono state definite, sono la soluzione perfetta per archiviare i dati forniti per quella chiamata proc memorizzata ...
bleepzter,

3
Ho anche dimenticato di menzionare che il DB risiede in Azure .... Non voglio introdurre un pasticcio nella gestione delle tabelle temporanee.
bleepzter,

La tabella delle variabili è la strada da percorrere. dichiarare @varTable Table (....)
ARLibertarian

1

Ho trovato la tua domanda cercando una soluzione allo stesso problema; e quali altre risposte non riescono a indicare è un modo per utilizzare una variabile per modificare il nome della tabella per ogni esecuzione della procedura in forma permanente, non temporanea.

Finora quello che faccio è concatenare l'intero codice SQL con le variabili da utilizzare. Come questo:

declare @table_name as varchar(30)
select @table_name = CONVERT(varchar(30), getdate(), 112)
set @table_name = 'DAILY_SNAPSHOT_' + @table_name

EXEC('
        SELECT var1, var2, var3
        INTO '+@table_name+'
        FROM my_view
        WHERE string = ''Strings must use double apostrophe''
    ');

Spero che sia d'aiuto, ma potrebbe essere complicato se il codice è troppo grande, quindi se hai trovato un modo migliore, per favore condividi!


-2
"SELECT *
  INTO 
    @TempCustomer 
FROM 
    Customer
WHERE 
    CustomerId = @CustomerId"

Ciò significa che è possibile creare una nuova @tempCustomertabella modificabile e inserire dati DAL Cliente. L'hai già dichiarato sopra, quindi non è necessario dichiararlo di nuovo. Meglio andare con

INSERT INTO @tempCustomer SELECT * FROM Customer

4
Non funziona Devi ancora dichiarare in anticipo la variabile della tabella.
Johan Boulé l'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.