SQL Server SELECT INTO @variable?


250

Ben mükemmel para cezası yürüten benim Sql (2008) Saklı Procs birinde aşağıdaki kodu var:

    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

Yani sizler için soru şu ki, şu konularda bir şeyler yapma olasılığı var:

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

Bu verileri aşağıdaki ifadelerde bellekten tekrar kullanabilmem için ne yapmalıyım? SQL Server, yukarıdaki ifade ile bir uyum atar, ancak ayrı değişkenler oluşturmak ve aynı tabloya karşı ayrı bir SELECT deyimi ile her birini başlatmak zorunda değilsiniz .... UGH !!!

Aynı tabloya karşı birden fazla sorgu olmadan satır boyunca bir şey elde etmek için herhangi bir öneriniz var mı?


1
"ayrı değişkenler oluşturmak ve her birini ayrı bir SELECT deyimi ile başlatmak için" - neden bunu yapmanız gerekir? declare @t tablebir kez ve tekrar kullanmanız gerekiyorsa, DELETE @TempCustomertekrar takmadan önce a
ateşleyin

Yanıtlar:


204

TABLO DEĞİŞKENLİĞİNİ SEÇEBİLEMEZSİNİZ. Yapabileceğiniz en iyi şey önce onu oluşturmak, sonra içine eklemektir. İkinci pasajınız

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
Bunun bir CTE bağlamında da işe yaradığını unutmayın. Bazinga!
Michael Krauklis

4
Herkesin neden gerçek bir geçici tablo ile sizin gibi bir tablo değişkenini seçemediğine dair bir cevabı var mı?
KSwift87

504

Bazı değişkenleri daha sonra kullanmak üzere atamak istiyorsanız, bunları tek bir satırda aşağıdaki satırlarda bir şeyle yapabilirsiniz:

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

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

Eğer peşinde olduğun şey buysa


1
En iyi cevap imho, ancak sonuçlar birden fazla olursa ne olur?
capitano666

Sonuçlar birden fazla ise mevcut değerlerden birini alırsınız. Bu ilginç bir bulmaca yapabilir! Bkz. Mssqltips.com/sqlservertip/1888/…
Smandoli

8
Sorguyu tek bir satır döndürmeye zorlamak için SELECT TOP 1
Adrian

1
@Adrian Evet, yukarıdaki sorgu tek bir satır seçtiğinizi varsayar. Daha süslü bir mantık istiyorsanız sipariş ve toplama işlevlerini de kullanabilirsiniz.
dougajmcdonald

1
OP'nin kullandığı veritabanı türünü kullanmıyorsanız Adrian'ın belirttiği gibi TOP 1'i desteklemez. SQL Server / MS Access TOP, MySQL LIMIT, Oracle ROWNUM kullanır. Daha fazla bilgi için w3schools.com/sql/sql_top.asp adresine bakın .
Tyler

33

Bunu yapabilirsiniz:

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

daha sonra

SELECT CustomerId FROM #tempCustomer

#tempCustomer'ın yapısını bildirmeniz gerekmez


3
@webturner Bu noktaların hiçbiri doğru değil. Geçici tablolar proc dışında kapsamlandırılmaz ve tablo değişkenleri geçici tablolardan daha fazla "yalnızca bellek" değildir.
Martin Smith

7
Bir eklemeyi unutmayın DROP TABLE #tempCustomerzaman #tempCustomerbir neden olacaktır artık başka türlü gerekli değildir sonraki seçme #tempCustomer already existshatası
ViRuSTriNiTy

15

Sözdiziminiz biraz bitmiş gibi görünüyor. Bunun bazı iyi örnekleri var

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

Daha sonra

SELECT CustomerId FROM @TempCustomer

2

Temp masalarý istiyor gibisin. http://www.sqlteam.com/article/temporary-tables

#TempTable'ın tüm SP'nizde kullanılabildiğini unutmayın.

## TempTable herkes tarafından kullanılabilir.


2
## temptable - sahibi (yaratıcısı)
silene

4
Geçici masa istemiyorum. Sıcaklık tabloları pahalı ve yavaştır. Ben sadece belirli bir kayıt için küçük bir süre için biraz veri tutmak ve daha sonraki aramalar olmadan, birden fazla sql deyimleri için kullanılabilir yapmak istiyorum. Tablo Değişkenleri, tanımlandıkları depolanmış süreç içinde kapsama sahip olduklarından, saklanan bir proc çağrısı için gönderilen verileri depolamak için mükemmel bir çözümdür ...
bleepzter

3
Ben de DB Azure içinde olduğunu söylemeyi unutmuşum .... Geçici tabloları yönetme dışında bir karışıklık tanıtmak istemiyorum.
bleepzter

Değişken tablo gidilecek yoldur. declare @varTable Tablo (....)
ARLibertarian

1

Sorunuzu aynı soruna bir çözüm ararken buldum; ve diğer cevapların işaret etmediği, yordamınızın her yürütülmesi için tablonun adını geçici değil kalıcı bir biçimde değiştirmek için bir değişken kullanmanın bir yoludur.

Şimdiye kadar ne tüm SQL kodu kullanılacak değişkenlerle bitiştirmek olduğunu. Bunun gibi:

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

Umarım yardımcı olur, ancak kod çok büyükse hantal olabilir, bu yüzden daha iyi bir yol bulduysanız, lütfen paylaşın!


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

Bu, yeni bir @tempCustomerdeğişkenli tablo oluşturma ve Müşteri'den veri ekleme anlamına gelir . Yukarıda zaten beyan etmişsinizdir, bu yüzden tekrar beyan etmeye gerek yoktur. Gitmek daha iyi

INSERT INTO @tempCustomer SELECT * FROM Customer

4
Çalışmıyor. Yine de tablo değişkenini önceden bildirmeniz gerekir.
Johan Boulé
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.