2009-04-16 20 views
6

Bir T-SQL yordamıyla uğraşıyorum ve yardımcı olabileceğinizi umuyorum.Bir boole sonucu veren T-SQL yordamı

Ben Bir satır Belirtilen kimliğe

  • Eğer bir (veya daha fazla) için bir tablo var

    1. eğer o zaman son birbirini kimlik 5.
    için belirledi var, biliyorum gerekir

    Bu nedenle, satırdan çıkarmamız gereken ilk tablonun iki ilgili kimliği vardır: CaseID ve LocationID, bunlar her iki tam sayıdır. İkinci tablonun StateID adlı 1 ilgili kimliği vardır.

    Şu anda satır bir tablo parçası var ama yakında bir şey yapmak için çalışırken Enterprise Manager SON deyimi önce sözdizimi hatası verip alabilirsiniz.

    CREATE PROCEDURE [dbo].[HasActiveCase] 
    (
        @LocationID INTEGER 
    ) 
    
    AS 
    
    DECLARE @CaseID AS INTEGER 
    SELECT @CaseID=CaseID FROM dbo.Cases WHERE @LocationID=LocationID 
    
    SELECT CASE WHEN 
        @CaseID IS NULL 
    THEN 
        0 
    ELSE 
        -- do something here to check CaseEvents.StateID is not 5 (closed) 
    END 
    GO 
    

    muhtemelen bir JOIN veya bir şey gerek ama burada tam bir acemi neysem almanın bir yolu yoktur.

    StateID'yi kontrol etmenin en kolay yolu (anlamak), 5 değil ve sonucu doğru/yanlış olarak döndürmektir? (Biliyorum SQLServer bir boole türü yok ama bunun yerine bir Bit türü var.)

    Ayrıca bir stil konusuna da: ID'lerdeki değerlerin onlarla ilişkili bir metin alanı var - CaseEvents.StateID var örneğin 'Kapalı' metni. Değerleri ID olarak döndürmeli ve sonra kimliği kodda mı değiştirmeli yoksa kimlikleriyle birlikte nesneleri değiştirdiyseler mi? Hiçbir zaman bir sette 20 veya 30'dan fazla sonuç alınmayacaktır ve tablo, 2000 sonuçları elde etmek için 5 yıl aldığı için asla çok büyük olmayacaktır.

    Not: linq (veya başka bir şey .NETty) kullanamazsınız, çünkü bu bir VB6 programından çağrılır.

    Güncelleme:

    sadece 1 vaka böylece yalnızca en son öğe alaka olacak bir anda açık olabilir. olması

    olası durumlar geçerli:

    1. Hiçbir durumda hiç açtı. Bu 0 değerini döndürmelidir.
    2. Daha önce bir vaka açılmış, ancak şimdi kapalı. Bu da 0 değerini döndürmelidir.
    3. Açık bir durum var. Bu sizin için çalışır, bu 1.
  • cevap

    8

    Düzenlendi; Var olan sorguda, birden fazla vaka varsa, yalnızca ilk sorgu tarafından seçili durumun ne zaman kapandığını kontrol edeceğine dair bir hata olduğunu unutmayın (tabi ki, yalnızca birden fazla Kasanın olması mümkün ise doğrudur). belirli bir yere atanmış).

    SELECT @CaseID = dbo.Cases.CaseID 
    FROM dbo.Cases 
        JOIN dbo.CaseEvents ON dbo.Cases.CaseEventID = dbo.CaseEvents.CaseEventID 
    WHERE @LocationID = dbo.Cases.LocationID 
        AND 5 != dbo.CaseEvents.StateID 
    
    SELECT CASE WHEN @CaseID IS NULL THEN CAST(0 AS BIT) ELSE CAST(1 AS BIT) END AS CaseExists 
    
    +0

    okuduğumda daha sonra belirttim. Benim durumumda, o anda sadece bir tane açık durumda olabilirsiniz, bu yüzden son öğenin bir kapanış olup olmadığını kontrol etmek yeterli olacaktır. Bunu problem açıklamasında belirtmeliyim. –

    +0

    Üzgünüm - sanırım "son durumun kapalı olup olmadığını kontrol et" dediğimde daha spesifik olmalıydım - Bu mutlaka en son değil, bir ORDER BY yan tümcesini açıkça içermedikçe, sipariş belirli olmayacaktır. –

    +0

    Sizinki kutudan çıkmış olan sizdiniz, anlamanız en kolay olmasa bile kene olsun. –

    4

    kontrol dönmelidir.

    Ben bu sorgu aradığınız yapacak düşünüyorum
    CREATE PROCEDURE [dbo].[HasActiveCase] 
    (
        @LocationID INTEGER 
    ) 
    
    AS BEGIN 
        DECLARE @CaseID AS INTEGER 
        SELECT @CaseID = CaseID FROM dbo.Cases WHERE @LocationID=LocationID 
    
        SELECT CASE WHEN 
         @CaseID IS NULL 
        THEN 0 
        ELSE CASE WHEN (SELECT COUNT(*) FROM CaseEvents WHERE StateID <> 5) > 0 THEN 0 ELSE 1 END 
        END 
    END 
    GO 
    
    +0

    ben Hata 156 al: 'BEGIN' anahtar kelimesinin yakınındaki Yanlış Sözdizimi. 'THEN' anahtar kelimesine yakın Doğru Sözdizimi. –

    +0

    Tekrar kontrol edin, düzeltildi, CASE sözdizimi için IF sözdizimi değiştirildi –

    +0

    Ancak, Edoode'nun cevabını da kontrol edin, bu da çok iyi –

    1

    Bu kadar iyi sonuç verebilir:

    CREATE PROCEDURE [dbo].[HasActiveCase] 
    (
        @LocationID INTEGER 
    ) 
    
    AS 
        IF EXISTS (SELECT CaseID FROM dbo.Cases WHERE @LocationID=LocationID) 
        BEGIN 
         IF EXISTS (SELECT * FROM CaseEvents WHERE StateID <> 5) 
         SELECT 1 ELSE SELECT 0 
        END 
        ELSE 
        SELECT 0 
    
    GO 
    
    +0

    Bazı nedenlerden dolayı bu, verilerin var olduğu iki durumdan birinde başarısız oluyor. Vaka 1 hiç bir zaman açılmadı - bu işe yarıyor. Vaka 2 daha önce açılmış durumda, ancak şimdi kapatıldı - bu geri dönüyor 1. Vaka 3, açılmış bir durumun var olduğu yer - bu, geri dönen 1. –

    +0

    @graham. Bazı örnek verilerle yardım edebilirim – edosoft

    1

    bu deneyin: yollarından

    Select Case When Exists 
         (Select * From CaseEvents 
         Where CaseId = 
          (Select CaseID From Cases 
          Where LocationId = @Location) 
         And StateId = 5) -- Or <> 5 I'm not sure which you want here 
         Then 1 Else 0 End 
    
    2

    sürü bu çözmek için, burada bir tane:

    CREATE PROCEDURE [dbo].[HasActiveCase] 
    (
        @LocationID INTEGER 
    ) 
    
    AS 
    
    DECLARE @CaseID AS INTEGER 
    SELECT @CaseID=CaseID FROM dbo.Cases WHERE @LocationID=LocationID 
    
    if (@CaseId IS NULL) 
    BEGIN 
        SELECT 0 
    END 
    ELSE if EXISTS (SELECT * FROM CaseEvents WHERE StatusId=5 and [email protected]) 
    BEGIN 
        SELECT 1 
    END 
    ELSE 
    BEGIN 
        SELECT 0 
    END 
    GO 
    
    -1
    create procedure abc (id int) 
    as 
    declare @count int 
    begin 
    select @count=count(anycolumn) from table 
    where [email protected] 
    if @count>0 
    return 1 
    else 
    return 0 
    end 
    
    +0

    Bu, ihtiyacım olanı yapmadı. –