SQL Server CASE deyimi tüm koşulları değerlendirir veya ilk TRUE koşulundan çıkar mı?


44

SQL Server (2008 veya 2012, özellikle) CASEifadesi tüm WHENkoşulları WHENdeğerlendirir mi veya doğru olarak değerlendirilen bir madde bulduğunda çıkar mı? Eğer bütün şartlar dizilimine uyuyorsa, bu doğru olanı değerlendiren son şartın, doğru olarak değerlendirilen ilk şartın üzerine yazdığı anlamına mı geliyor? Örneğin:

SELECT
    CASE
        WHEN 1+1 = 2 THEN'YES'
        WHEN 1+1 = 3 THEN 'NO'
        WHEN 1+1 = 2 THEN 'NO' 
    END

Sonuç, en son ne zaman koşulun "HAYIR" olarak değerlendirilebilmesine rağmen "YES" dir. İlk DOĞRU koşulu bulduğunda çıkar gibi görünüyor. Bu ise, bir kullanıcı onayla Lütfen artık durum .


5
Çok yakından ilişkili: İlk argüman NULL olmasa bile SQL Server bir COALESCE işlevinin tamamını okuyor mu? ( COALESCE()bir CASEifadeye tercüme edildiği gibi .)
ypercubeᵀᴹ

Yanıtlar:


46

İlk input_expression = when_expression ifadesinin TRUE değerine dönüştüğünü verir .

Referans http://msdn.microsoft.com/en-us/library/ms181765.aspx


Bu standart SQL davranışıdır:

  • Bir CASEifade ilk gerçek koşulu değerlendirir.

  • Gerçek bir koşul yoksa, bu ELSEkısmı değerlendirir .

  • Eğer gerçek bir durum yoksa ve hiçbir ELSEparça yoksa , bunu değerlendirir NULL.


2
Sadece doğru olarak değerlendirecek 3 durum koşulunun olması durumunda, sadece gerçek 2 olarak değerlendirilse de, gerçek olarak değerlendirilen ilk kişinin görevini yerine getirmesini istiyorum. ). Sorularımdaki örnek sorgudan durum böyle görünüyor. Sadece onaylamak istedim. Ayrıca SQL'in CASE koşullarını Yukarıdan Aşağıya okuduğunu umuyordum. Teşekkürler!
Juan Velez

15

SQL Server, genellikle CASE ifadeleri için kısa devre değerlendirmesi yapar ( SQLFiddle ):

--Does not fail on the divide by zero.
SELECT 
   CASE 
      WHEN 1/1 = 1 THEN 'Case 1'
      WHEN 2/0 = 1 THEN 'Case 2'
   END;

--Fails on the divide by zero.
SELECT 
   CASE 
      WHEN 1/1 = 99 THEN 'Case 1'
      WHEN 2/0 = 99 THEN 'Case 2'
   END;  

Ancak, SQL Server 2012'den itibaren doğru kısa devre yapmayan birçok ifade tipi vardır. Yorumlardaki ypercube bağlantısına bakınız.

Oracle her zaman kısa devre değerlendirmesi yapar . Bkz 11.2 SQL Dili Referansı . Veya aşağıdakileri karşılaştırın ( SQLFiddle ):

--Does not fail on the divide by zero.
SELECT
  CASE 
    WHEN 1/1 = 1 THEN 'Case 1'
    WHEN 2/0 = 1 THEN 'Case 2'
  END
FROM dual;


--Fails on the divide by zero.
SELECT
  CASE 
    WHEN 1/1 = 99 THEN 'Case 1'
    WHEN 2/0 = 99 THEN 'Case 2'
  END
FROM dual;

Bu aynı test MySQL ile yapılamaz, çünkü sıfır için bölmeye NULL döner. ( SQL Fiddle )


Peki ya bu ?: SQL-Fiddle
ypercubeᵀᴹ


@ ypercube Bu gerçekten ilginç bir davranış. Diğer kısımda çalıştırılacak kodu değerlendirir, ancak diğer WHEN ifadelerinin ne olduğuna ve sıfıra bölünmenin bir MIN içinde olup olmamasına bağlı olarak onu görmezden geliyor gibi görünmektedir. Bakınız sqlfiddle.com/#!6/d41d8/4468
Leigh Riffel

@ypercube Şimdi gönderdiğiniz bağlantının bir kısmını okuduğumuza göre, SQL Server'ın kısa devre değerlendirmesinin yapılıp yapılmadığına dair cevabın - genellikle?
Leigh Riffel

3
Evet, "genellikle" üzerinde hemfikirdim. Aaron'un cevabına işaret ettiği gibi, bir test "CASE her zaman kısa devreleri" yanlışlamak için yeterlidir. Ama genellikle yapar.
ypercubeᵀᴹ

7

MS SQL Server'ın da kısa devre değerlendirmesi kullandığı anlaşılıyor.

Aşağıdaki testte 3 testim var. Birincisi her zaman doğrudur, ikincisi tabloya başvurmadan başarısız olur ve üçüncüsü sadece veriler dikkate alındığında başarısız olur.
Bu özel çalışmada, her iki satır başarıyla döndürülür. İlk WHEN’i ya da ilk ve ikinci yorumları yaparsam başarısız olurum.

CREATE TABLE casetest (test varchar(10))
GO
INSERT INTO casetest VALUES ('12345'),('abcdef')
GO

SELECT CASE WHEN LEN(test)>1 THEN test
        WHEN 1/0 = 1 THEN 'abc'
        WHEN CAST(test AS int) = 1 THEN 'def'
        END
FROM casetest
GO

1

Durumda kullanılan case ifadesi WHEREve ifade tablodaki sütun değerlerini değerlendirmeyi içerdiğinde ilk durum ve tablodaki ilk satır bu koşulu sağlamazsa, case ifadesi ifadesi bir sonraki duruma gidecektir.

declare @tbl table(id int)
insert into @tbl values(1)
insert into @tbl values(2)
insert into @tbl values(3)

--Fails on the divide by zero.
SELECT * FROM @tbl
where  CASE 
        WHEN id = 2 THEN 1 -- first row in table will not satisfy the condition
        WHEN 2/0 = 1 THEN 1
        ELSE 0
      END =1

-- when filter the records to only who will staisfy the first case when condition, it 
will not fail on the divide by zero
SELECT * FROM @tbl
where ID=2 and -- first row in table will  satisfy the condition
  CASE 
    WHEN id = 2 THEN 1
    WHEN 2/0 = 1 THEN 1
    ELSE 0
  END =1

1

MySQL'de ilk gerçek seçenekte case ifadesinden çıkar. Birden çok gerçek değer olasılığına sahipseniz, tercih edilen cevabı daha önce diziye yerleştirmek istersiniz.


Soru SQL Server'la ilgili.
James Anderson
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.