T-SQL'de bir tablo değişkenine SEÇ


372

Tablo değişkenine tüm satırları eklemek istediğim karmaşık bir SELECT sorgusu var, ancak T-SQL buna izin vermiyor.

Aynı satırlar boyunca, SELECT INTO veya INSERT EXEC sorgularıyla bir tablo değişkeni kullanamazsınız. http://odetocode.com/Articles/365.aspx

Kısa bir örnek:

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

Tablo değişkenindeki veriler daha sonra farklı tablolara eklemek / güncellemek için kullanılır (çoğunlukla aynı verilerin küçük güncellemelerle kopyası). Bunun amacı, komut dosyasını SELECT INTOdoğrudan doğru tablolara yapmaktan biraz daha okunabilir ve daha kolay özelleştirilebilir hale getirmektir . Performans bir sorun değildir, çünkü rowcountoldukça küçüktür ve sadece gerektiğinde manuel olarak çalıştırılır.
... ya da sadece her şeyi yanlış yapıp yapmadığımı söyle.

Yanıtlar:


601

Bunun gibi bir şey deneyin:

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;

2
UserData tablosuna ekleyeceğiniz değerler olarak "SELECT name, myTable'dan konum" seçerseniz, seçimdeki değişkenlerin adlarının tablo tanımındaki adlarla eşleşmesi önemli değildir. UserData 'name' değişkenine gitmek için 'name' seçiyorsunuz, ancak 'location' seçiyorsunuz ve bir şekilde UserData 'oldlocation' değişkenine ataıyorsunuz. SQL bunları otomatik olarak eşler mi yoksa bir tür istisna atar mı?
Aran Mulholland

Adı önemli değil, sadece sütun türü.
CristiC

5
Vay bu tür bir anlam ifade ediyor ama aynı zamanda içimdeki ayrıştırıcı biraz kırgın hissediyorum :)
Aran Mulholland

Bunu UPDATE deyimlerinde kullanamıyorum: gist link
Paul-Sebastian Manole

1
Insert deyiminde, sütunları açıkça bildirmezseniz, tıpkı select * gibi, orijinal create table deyiminde bildirilen sırada eşlenirler. Bu nedenle, select deyimindeki konum, @userData tablosundaki oldlocation ile eşlenir, çünkü select, seçimin sonuç kümesinde konum 2'dir ve oldlocation, tablo tanımındaki sütun 2'dir. Dedi ki, bunu asla yapma. Sütunların veya satırların veritabanı sıralamasına güvenilmemelidir. Bu konuda daima açık olun.
absmiths

94

Amacı SELECT INTO(dokümanlar başına, benim vurgu)

To oluşturmak başka tablodaki değerlerden Yeni bir tablo

Ama zaten var bir hedef tablo! Yani ne istiyorsun

INSERTDeyim bir tabloya bir veya daha fazla yeni satırlar ekler

Veri değerlerini aşağıdaki şekillerde belirleyebilirsiniz:

...

SELECTBir veya daha fazla satır için veri değerlerini belirtmek üzere bir alt sorgu kullanarak , örneğin:

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

Ve bu sözdiziminde MyTabletablo değişkeni olmasına izin verilir .


1
Gerçekten kabul edilen cevabın bu bilgiyi içermesini diliyorum!
Davie Brown

MyTable bunu "Geçersiz Nesne Adı" olduğunu alıyorum, bu yüzden bu cevap eksik bir şey var.
Mike Flynn

@MikeFlynn , gerçek tablonuzun adı için MyTablebir yer tutucudur . Ben bir tablo ile gerçek veritabanları olduğunu sanmıyorum ...MyTable
AakashM

Ve SELECT INTO ile bir tablo değişkeni oluşturmak / bildirmek istersem ...? Örneğin, tablo değişkeninin sütunlarını t1.somecolumn, t1.othercolumn, t2 olarak tanımlamak için. *
Armando

27

Geçici veri kümelerini saklamak için ortak tablo ifadelerini de kullanabilirsiniz. Daha zarif ve adhoc dostudurlar:

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

Bunu sev! Teşekkür ederim.
fourpastmidnight

Bunun bir kopya oluşturduğunu sanmıyorum, userData'dan silerseniz veya güncellerseniz orijinal tablolarınızdaki kayıtları silmez ve güncellemez mi?
atreeon

Evet, CTE birleştirme, birlikler vb. Kullanarak birden çok tabloya
başvurmadığı sürece CTE'deki

2
Bunun dezavantajı, CTE tablosunu yalnızca hemen aşağıdaki komutlarda kullanabilmenizdir. CTE'nin çalışmadığı herhangi bir nedenle sonuç kümesinden birden fazla geçiş yapmanız gerekiyorsa. OP, birden fazla değişikliğin yapılacağını ima ediyor gibi görünüyor, bu durumda bu çalışmaz - "Tablo değişkenindeki veriler daha sonra farklı tablolara eklemek / güncellemek için kullanılır (çoğunlukla aynı verilerin küçük kopyalarla kopyalanması) güncellemeleri)."
Tony

16

Geçici tabloları kullanmayı deneyebilirsiniz ... bir uygulamadan yapmıyorsanız. (Bunu manuel olarak çalıştırmak uygun olabilir)

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

Tabloyu bu şekilde bildirme çabasını atlarsınız ... Geçici sorgular için yardımcı olur ... Bu, aynı oturumda olmadıkça diğer oturumlar tarafından görülmeyecek yerel bir geçici tablo oluşturur. Bir uygulamadan sorgu çalıştırıyorsanız bir sorun olabilir.

bir uygulamada çalışmasını istiyorsanız, şu şekilde beyan edilen değişkenleri kullanın:

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;

Düzenleme: birçoğunuz bağlantıdan oturum için güncellenmiş görünürlük belirttiğiniz gibi Geçici tablolar oluşturmak web uygulamaları için bir seçenek değildir, çünkü oturumlar yeniden kullanılabilir, bu durumlarda geçici değişkenlere bağlı kalın


2
Maalesef, CREATE TABLE haklarına sahip olmadığımı belirtmeyi unuttum.
Indrek

6
Bir temp oluşturmanın biraz daha fazla yükü vardır.
paparazzo

2
geçici tablo kullanmak her zaman güvenli değildir. Örneğin, web hizmetleri. Sunucudaki maksimum bağlantıyı sınırlamak ve SQL'i biraz daha korumak için tek bir bağlantıya sahip web servisleriyle, her sorgudan geçiş için geçici tablo bulunacak ve şu anda onu kullanan birinin üzerine yazabilecektir.
Franck

12
@Franck - Genel bir geçici tablo (iki karma önek) kullanırsanız, doğru olursunuz. Bununla birlikte, yerel bir geçici tablo (bir karma önek) tek bir oturuma (tek bağlantı olarak da bilinir) yalıtılacaktır; bu nedenle, tüm istekler için tek bir bağlantı kullanmadığınız sürece ( tavsiye). Yine de olası performans sonuçları devam etmektedir.
maf748

@GazB Elbette, yan etkisi olan herhangi bir ifadenin a function. Deneyimlerime göre, birisinin bu tür ifadelere ihtiyaç duyduğunu düşündüğü çoğu durumda, bu aslında kendi düşüncelerini yeniden düşünmeleri gerektiği anlamına gelir function- veya en azından bir procedure. En azından kendim için konuşuyorum. :-)
underscore_d

8

Şunun INSERTyerine kullanmayı deneyin SELECT INTO:

INSERT @UserData   
SELECT name, location etc.

5

İlk olarak bir geçici tablo oluşturun:

Aşama 1:

create table #tblOm_Temp (

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

** Adım 2: ** Temp tablosuna bir değer ekleyin.

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

Adım 3: Tablo bildirme Geçici tablo verilerini tutacak değişken.

declare   @tblOm_Variable table(

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

Adım 4: Temp tablosundan değer seçin ve tablo değişkenine ekleyin.

insert into @tblOm_Variable select * from #tblom_temp

Son olarak, değer geçici tablodan Tablo değişkenine eklenir

Adım 5: Girilen değeri tablo değişkeninde kontrol edebilir.

select * from @tblOm_Variable

1

Tamam, Şimdi yeterince çaba ile ben aşağıdakileri kullanarak @table eklemek mümkün:

INSERT @TempWithheldTable SEC
a.SuspendedReason, a.SuspendedNotes, a.SuspendedBy, openrowset DAN a.ReasonCode (bulk 'C: \ veri tabanları \ WithHeld.csv', FORMATFILE = N'C: \ veri tabanları \ Format.txt',
Errorfile = N'C: \ Temp \ MovieLensRatings.txt ') AS;

Buradaki en önemli şey, eklenecek sütunları seçmektir.


Bir tablo değişkeni "@TempWithheldTable" derleme hata iletisi bildirmeliyim
atreeon

-5

SELECT INTO kullanmanın bir nedeni, KİMLİK kullanmanıza izin vermesidir:

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

Bu çok kötü bir tablo değişkeni ile işe yaramaz ...


6
IDENTITYYine de sütun içeren bir tablo değişkeni bildirebilirsiniz .
Martin Smith
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.