SQL Server SELECT INTO @variable?

250

Saya memiliki kode berikut di salah satu Sql saya (2008) Disimpan Procs yang mengeksekusi dengan baik:

    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

Jadi pertanyaan untuk kalian adalah apakah ada kemungkinan untuk melakukan sesuatu seperti:

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

Sehingga saya bisa menggunakan kembali data ini dari memori dalam pernyataan berikut lainnya? SQL Server cocok dengan pernyataan di atas, namun saya tidak ingin harus membuat variabel terpisah dan menginisialisasi masing-masing melalui pernyataan SELECT terpisah terhadap tabel yang sama .... UGH !!!

Ada saran tentang cara mencapai sesuatu di sepanjang baris tanpa beberapa pertanyaan terhadap tabel yang sama?

bleepzter
sumber
1
"untuk membuat variabel yang terpisah dan menginisialisasi masing-masing melalui pernyataan SELECT yang terpisah" - mengapa Anda perlu melakukan itu? declare @t tablesekali, dan jika Anda perlu menggunakannya kembali, tembak DELETE @TempCustomersebelum memasukkan ke dalamnya lagi
RichardTheKiwi

Jawaban:

204

Anda tidak dapat PILIH .. MENJADI .. VARIABEL TABEL. Yang terbaik yang dapat Anda lakukan adalah membuatnya terlebih dahulu, lalu masukkan ke dalamnya. Cuplikan ke-2 Anda harus

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
RichardTheKiwi
sumber
5
Harus dicatat bahwa ini berfungsi dengan baik dalam konteks CTE juga. Bazinga!
Michael Krauklis
4
Adakah yang punya jawaban mengapa seseorang tidak bisa memilih ke dalam variabel tabel seperti Anda bisa dengan tabel sementara yang sebenarnya?
KSwift87
504

Jika Anda ingin menetapkan beberapa variabel untuk digunakan nanti, Anda dapat melakukannya dalam satu kesempatan dengan sesuatu di sepanjang baris ini:

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

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

Jika itu tipe yang Anda cari

dougajmcdonald
sumber
1
Jawaban terbaik imho, tetapi apa yang terjadi jika hasilnya lebih dari satu?
capitano666
Jika hasilnya lebih dari satu, Anda akan mendapatkan salah satu dari nilai yang tersedia. Itu bisa menjadi teka-teki yang menarik! Lihat mssqltips.com/sqlservertip/1888/…
Smandoli
8
Untuk memaksa kueri mengembalikan satu baris, gunakan SELECT TOP 1
Adrian
1
@Adrian Ya, kueri di atas menganggap Anda telah memilih satu baris. Anda juga dapat menggunakan fungsi pemesanan dan agregat jika Anda menginginkan logika yang lebih mewah.
dougajmcdonald
1
Jika Anda tidak menggunakan tipe database yang digunakan OP, tidak semua mendukung TOP 1 seperti yang disebutkan Adrian. SQL Server / MS Access menggunakan TOP, MySQL menggunakan LIMIT, dan Oracle menggunakan ROWNUM. Lihat w3schools.com/sql/sql_top.asp untuk informasi lebih lanjut.
Tyler
33

kamu bisa melakukan ini:

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

lalu nanti

SELECT CustomerId FROM #tempCustomer

Anda tidak perlu mendeklarasikan struktur #tempCustomer

Victor Ribeiro da Silva Eloy
sumber
3
@ webturner Tak satu pun dari poin itu benar. Tabel temp tidak dicakup di luar proc dan variabel tabel tidak lagi "hanya memori" dari tabel temp.
Martin Smith
7
Jangan lupa untuk menambahkan DROP TABLE #tempCustomersaat #tempCustomertidak diperlukan lagi jika tidak, pilih berikutnya akan menyebabkan #tempCustomer already existskesalahan
ViRuSTriNiTy
15

Sepertinya sintaks Anda sedikit keluar. Ini memiliki beberapa contoh bagus

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

Lalu nanti

SELECT CustomerId FROM @TempCustomer
Pat L
sumber
2

Kedengarannya seperti Anda ingin tabel temp. http://www.sqlteam.com/article/turnal-tables

Perhatikan bahwa #TempTable tersedia di seluruh SP Anda.

Perhatikan bahwa ## TempTable tersedia untuk semua.

Valamas
sumber
2
## temptable - hingga pemilik (pencipta) menghapusnya atau terputus
RichardTheKiwi
4
Saya tidak ingin tabel temp. Tabel temp mahal dan lambat. Saya hanya ingin menyimpan sedikit data untuk catatan tertentu untuk sedikit waktu dan membuatnya tersedia untuk beberapa pernyataan sql, tanpa pencarian berikutnya. Karena Variabel Tabel memiliki cakupan dalam proc tersimpan yang telah ditentukan, mereka adalah solusi sempurna untuk menyimpan data tuppled untuk satu panggilan proc yang disimpan ...
bleepzter
3
Saya juga lupa menyebutkan bahwa DB berada di Azure .... Saya tidak ingin memperkenalkan kekacauan mengelola tabel temp.
bleepzter
Tabel variabel adalah caranya. mendeklarasikan @varTable Table (....)
ARLibertarian
1

Saya menemukan pertanyaan Anda mencari solusi untuk masalah yang sama; dan jawaban lain yang gagal ditunjukkan adalah cara menggunakan variabel untuk mengubah nama tabel untuk setiap eksekusi prosedur Anda dalam bentuk permanen, bukan sementara.

Sejauh ini yang saya lakukan adalah menggabungkan seluruh kode SQL dengan variabel yang akan digunakan. Seperti ini:

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''
    ');

Saya harap ini membantu, tetapi bisa jadi rumit jika kodenya terlalu besar, jadi jika Anda telah menemukan cara yang lebih baik, silakan bagikan!

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

Yang berarti membuat @tempCustomertablevariable baru dan memasukkan data DARI Pelanggan. Anda sudah mendeklarasikannya di atas sehingga tidak perlu lagi menyatakan. Lebih baik pergi

INSERT INTO @tempCustomer SELECT * FROM Customer
koushik veldanda
sumber
4
Itu tidak bekerja. Anda masih perlu mendeklarasikan variabel tabel terlebih dahulu.
Johan Boulé