2009-04-16 11 views
6

Mam problem z procedurą T-SQL i mam nadzieję, że możesz pomóc.Procedura T-SQL dająca wynik boolowski

muszę wiedzieć, czy

  1. A wiersz istnieje w tabeli dla danego ID
  2. Jeżeli jeden (lub więcej) istnieje wtedy ostatni z nich ma inny identyfikator ustawiony na 5.

Pierwsza tabela, z której chcemy pobrać wiersz, ma dwa odpowiednie identyfikatory: Identyfikator sprawy i Identyfikator lokalizacji, są to liczby całkowite. Druga tabela ma 1 odpowiedni identyfikator o nazwie StateID.

Obecnie mogę sprawdzić, czy wiersz istnieje w części tabeli, ale już wkrótce, gdy spróbuję zrobić wszystko, Enterprise Manager podaje błąd składni przed instrukcją END.

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 

Prawdopodobnie istnieje sposób na zdobycie tego, czego potrzebuję w DOŁĄCZU lub coś w tym rodzaju, ale jestem tutaj kompletnym nowicjuszem.

Jaki byłby najłatwiejszy do zrozumienia sposób sprawdzenia identyfikatora StateID, to nie 5 i zwrócenie wyniku jako true/false? (Wiem, że SQLServer nie ma typu boolowskiego, ale zamiast tego ma typ Bit.)

Również w kwestii stylu: Wartości w identyfikatorach mają powiązane z nimi pole tekstowe - CaseEvents.StateID ma na przykład tekst "Zamknięte". Czy należy zwracać wartości jako identyfikatory, a następnie zastępować identyfikator kodem lub zwracać obiekty z identyfikatorami już zastąpionymi przez tekst? Nigdy nie będzie więcej niż 20 lub 30 wyników zwróconych w zestawie i tabela nigdy nie będzie bardzo duża, ponieważ zajęło 5 lat, aby uzyskać 2000 wyników w nim.

UWAGA: Nie można użyć linq (ani niczego innego .NETty), ponieważ zostanie wywołany z programu VB6.

Aktualizacja:

tylko 1 przypadek może być otwarte w czasie, więc tylko najnowsza pozycja byłaby znaczenie.

Możliwe sytuacje mieć to:

  1. No sprawa nigdy otwarte. Powinno to zwrócić 0.
  2. Sprawa została poprzednio otwarta, ale została zamknięta. To również powinno zwrócić 0.
  3. Otwarty przypadek istnieje. Powinno to powrócić 1.

Odpowiedz

8

Myślę, że to zapytanie zrobi to, czego szukasz; Zauważ, że twoje istniejące zapytanie ma błąd, że jeśli istnieje więcej niż jeden przypadek, to tylko sprawdzi, czy jakikolwiek przypadek został wybrany przez zapytanie początkowe jest zamknięty (oczywiście jest to prawdą tylko wtedy, gdy możliwe jest posiadanie więcej niż jednego przypadku przypisane do konkretnej lokalizacji).

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

W moim przypadku można mieć tylko 1 przypadek otwarty w momencie, więc sprawdzanie, czy ostatni element jest zamknięciem, wystarczy w tym przypadku. Powinienem to zauważyć w opisie problemu. –

+0

Przepraszam - myślę, że powinienem być bardziej szczegółowy, gdy powiedziałem "sprawdź, czy ostatnia sprawa jest zamknięta" - niekoniecznie jest to najnowsza, kolejność nie będzie konkretna, chyba że wyraźnie dodasz klauzulę ORDER BY. –

+0

Twój to był ten, który działał prosto z pudełka, więc dostajesz kleszcza, nawet jeśli nie jest to najłatwiejsze do zrozumienia. –

4

Sprawdź, czy to działa dla Ciebie. Edytowane

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

I Uzyskaj błąd 156: Niepoprawna składnia w pobliżu słowa kluczowego "BEGIN'.Niepoprawna składnia w pobliżu słowa kluczowego" THEN ". –

+0

Sprawdź ponownie, poprawiłem, zmieniono składnię IF dla CASE składni –

+0

Jednak sprawdź odpowiedź Edoode, która jest również bardzo dobra. –

1

To może działać także:

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

Z jakiegoś powodu nie powiedzie się w jednym z dwóch przypadków, gdy dane istnieją. Przypadek 1 nigdy nie był otwarty - to działa. Przypadek 2 to sprawa, która została poprzednio otwarta, ale teraz jest zamknięta - to się nie powraca 1. Przypadek 3 jest tam, gdzie istnieje otwarty przypadek - ten powraca po powrocie 1. –

+0

@graham. Przy niektórych przykładowych danych mogę pomóc – edosoft

1

Spróbuj tego:

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

wiele sposobów, aby rozwiązać ten problem, tu jest jeden:

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 CaseId=[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

To nie robi tego, czego potrzebowałem. –