Neden bir sütunun var olup olmadığını SELECT değil bir sütun görmek için kullanamıyorum?


17

Böyle bir şey neden çalışmıyor?

SELECT
CASE 
WHEN NULLIF(COL_LENGTH('Customers', 'Somecol'), '') IS NULL THEN NULL
ELSE Somecol
END AS MyTest
FROM Customers;

Ben sadece sütun var olup olmadığını kontrol ediyorum, ancak SQL Server Somecolmevcut değil şikayet ediyor . Tek bir ifadede buna bir alternatif var mı?


3
Bunu neden yapmak istediğinize dair bir örnek var mı? Neden bulunmayan bir sütundan seçim yapmaya çalışan bir sorgu yazmak istediğinizi anlayamıyorum.
Mark Sinkinson

4
SQL Server, deyim sözdiziminizi çalıştırmadan önce doğru olduğunu değerlendirir. Bu nedenle, başvurulan tüm sütunlar, bir CASEdeyim içine sarılmış olsalar bile tablolarda bulunmalıdır .
Mark Sinkinson

@MarkSinkinson: Sözdiziminden sonra adlar denetlenir , ancak evet, SQL Server toplu işi çalıştırmadan önce bunu yapar.
Andriy M

1
Aralarından seçim yapmak INFORMATION_SCHEMAgeçici bir çözüm olarak kullanılabilir.
Brilliand

Yanıtlar:


43

Aşağıdaki sorgu ile aynı fikri kullanan bu şaşırtıcı bir cevap ile ypercube :

SELECT x.*
FROM (SELECT NULL AS SomeCol) AS dummy
CROSS APPLY
(
  SELECT
    ID,
    SomeCol AS MyTest
  FROM dbo.Customers
) AS x;

Şöyle çalışır:

  • eğer dbo.Customersadlı bir sütun vardır SomeCol, o zaman SomeColiçinde SomeCol AS MyTestolarak çözecektir dbo.Customers.SomeCol;

  • tablonun böyle bir sütunu yoksa, başvuru hala geçerli olacaktır, çünkü şimdi şu şekilde çözümlenecektir dummy.SomeCol: dummysütunlar bu bağlamda başvurulabilir.

Bu şekilde birden çok "yedek" sütun belirtebilirsiniz. Hile, bu tür sütunlar için tablo takma adını kullanmak değildir (çoğu durumda kaşlarını çatmış bir uygulamadır, ancak bu durumda tablo takma adını atlamak sorunu çözmenize yardımcı olur).

Tablo bir birleşimde kullanılırsa ve diğer tablonun kendi tablosu varsa SomeCol, hile çalışmasını sağlamak için birleştirme işleminde kullanmadan önce yukarıdaki sorguyu türetilmiş bir tablo olarak kullanmanız gerekebilir:

SELECT ...
FROM
(
  SELECT x.*
  FROM (SELECT NULL AS SomeCol) AS dummy
  CROSS APPLY (
    SELECT
      ID,
      SomeCol AS MyTest
    FROM dbo.Customers
  ) AS x
) AS cust
INNER JOIN ...
;

1
SQL derleyicisinin sadece biraz karmaşık olup olmadığını merak ediyorum. Süper serin ne yapabilirim.
Max Vernon

9

Bunu yapmanın bir yolu, sütunların varlığını kontrol etmek ve ardından bu sütunun var olup olmamasına bağlı olarak Dinamik SQL'i oluşturmaktır.

Dinamik SQL olmadan, SQL Server ifadeyi yürütmeden önce sütunun var olup olmadığını değerlendirmeye çalışarak hataya neden olur.

Bununla birlikte, gelecekte yazmak ve potansiyel olarak değiştirmek için 2 sorgunuz olacağı anlamına gelir. Ancak, var olmayan SELECTsütunlardaki ifadeleri gerçekten hedeflemeniz gerektiğine inanmıyorum .

declare @SQL varchar(max)

If exists (select 1 from sys.columns where Name = N'NameOfColumn' and object_id=object_id(N'yourTableName'))
begin
set @SQL = 'select ID, NameOfColumn from yourTableName'
exec(@sql)
end
else
begin
Print 'Column does not exist'
end

Evet, bununla birlikte, mantıklı olan tek bir açıklamada olmalıdır. Sonuçta, muhtemelen var olmayan bazı sihirli sistem işlevlerini arıyorum.
Carson Reinke

4

Tabloda olabilecek sütunları sorgulamak için bazı XML'lerden yararlanabilirsiniz .

Çapraz uygula satır başına tüm sütunlardan bir XML oluşturun ve values()işlevi kullanarak değeri ayıklayın .

Bu sorgu kimliği bilinir bu yüzden doğrudan tablodan alın. Col1 ve Col2 orada olabilir veya olmayabilir XML kullanarak onları olsun.

select T.ID,
       TX.X.value('(Col1/text())[1]', 'int') as Col1,
       TX.X.value('(Col2/text())[1]', 'int') as Col2
from T
  cross apply (select T.* for xml path(''), type) as TX(X)

SQL Keman


-1

Benim yaklaşımım diğerlerinden biraz farklı. Ben sistemi bunun için kullanmayı tercih ve sadece bir sayı almak çünkü bir sorgu üstündeki bir değişkene sütun sayısını atamak ve daha sonra buna göre devam etmek ya da değil seçebilirsiniz. Bunun dezavantajı… birden çok tabloda aynı sütun adına sahipseniz, sütunun sorgulamak istediğiniz tabloda bulunduğundan emin değilsiniz. Ancak, sadece belirli bir sayı almak istediğiniz için teknik belirli tablolarda da çalışır.

Özellikle sorma ile ilgili 'sorun' - yaşadığınız sorun. Genel olarak, bir NULL değeri sorunlara neden oluyorsa ... varlığını doğrulamanın başka bir yolunu bulun. Bu, sunucuyu bozma riski olmadan bunu yapmanın bir yoludur.

SELECT COUNT(*) FROM sys.columns WHERE sys.columns.name = 'FarmID'

1
sysobjectsBelirli tablonun böyle bir sütunu olup olmadığını kontrol etmek için neden sorgunuzda da kullanmıyorsunuz ?
ypercubeᵀᴹ

Evet… Bunun yapılabileceğinden bahsettim… hatta sorguladığınız tabloda da aynı şeyi yapabilirsiniz… COUNT kullanımı için genel biçimi gösterdim çünkü COUNT, SIFIR olduğu zaman COUNT hata vermiyor ve ... bir değişkene de atayabileceğinizi belirtin. (örneğin SEÇİM SAYISI SEÇİN (*) myVarName…)
jinzai

1
Bunun Mark'ın sorgusundan nasıl daha iyi olacağını göremiyorum. SELECT 1 ...hata yapmaz.
ypercubeᵀᴹ

Daha iyi olduğunu söylemedim, ama aynı sonucu elde etmenin çok daha basit bir yolu. SELECT 1 hata vermeyebilir, ancak COUNT ile aynı şey değildir. SELECT, NOM olsa bile SOMETHING döndürür. COUNT öğenin yalnızca tek bir sayı döndürmesi gerekiyor. Bu şekilde daha hızlı olur ve sayımın daha sonra kullanılabileceğinden bahsettim.
jinzai

Saymaya ihtiyacınız varsa tamam. Ama EXISTS (SELECT ...)genellikle (SELECT COUNT(*) ...)diğerlerinden daha hızlı değil , daha hızlıdır .
ypercubeᵀᴹ

-3

Doğru anladıysam ...

Sorguyu aşağıdaki gibi bir şey kullanabilir ve sayıya göre hareket edebilirsiniz ... Sayım> 1 ise, bu tabloda col bulunduğunuz anlamına gelir ve count = 0 ise, tablo

SEÇ sayısı (*)
COLUMN_NAME NEREDEN ('Id')
VE TABLE_SCHEMA = 'dbo' ve TABLE_NAME = 'UserBase' dan BİLGİ_SCHEMA.COLUMNS.


4
Hayır, doğru anlamadın. Ayrıca @AaronBertrand'dan Kin_SHEMA görüntülemelerine karşı davayı kontrol edin
Kin Shah
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.