2009-04-16 12 views
6

Ich habe Probleme mit einem T-SQL-Verfahren und hoffe, dass Sie helfen können.T-SQL-Prozedur mit einem booleschen Ergebnis

Ich muss wissen, ob

  1. Eine Reihe für eine bestimmte ID in einer Tabelle vorhanden ist
  2. Wenn eine (oder mehrere) existiert dann das späteste hat eine andere ID auf 5 gesetzt

Also die erste Tabelle, die wir brauchen, um die Zeile zu bekommen, hat zwei relevante IDs: Die CaseID und die LocationID, das sind beides ganze Zahlen. Die zweite Tabelle hat 1 relevante ID namens StateID.

Momentan kann ich herausfinden, ob die Zeile in einem Tabellenabschnitt existiert, aber sobald ich versuche etwas zu tun, gibt Enterprise Manager vor der END-Anweisung einen Syntaxfehler aus.

Es gibt wahrscheinlich einen Weg, um zu bekommen, was ich in einem JOIN oder etwas brauche, aber ich bin ein kompletter Neuling hier.

Was wäre die einfachste (zu verstehen) Art der Überprüfung der StateID ist nicht 5 und das Ergebnis als ein wahr/falsch? (Ich weiß, dass SQLServer keinen booleschen Typ hat, sondern stattdessen einen Bit-Typ hat.)

Auch eine Frage des Stils: Den Werten in den IDs ist ein Textfeld zugeordnet - CaseEvents.StateID hat der Text 'Geschlossen' zum Beispiel. Sollte ich Werte als IDs zurückgeben und dann die ID im Code ersetzen oder die Objekte zurückgeben, deren IDs bereits durch den Text ersetzt wurden? Es werden nie mehr als 20 oder 30 Ergebnisse in einem Satz zurückgegeben und die Tabelle wird nie sehr groß sein, da es 5 Jahre dauert, um 2000 Ergebnisse zu erhalten.

HINWEIS: Kann linq (oder irgendetwas anderes .NETty) nicht verwenden, weil dies von einem VB6-Programm aufgerufen wird.

aktualisieren:

Nur 1 Fall kann zu einer Zeit, so dass nur die neuesten Artikel von Relevanz wären offen.

Die möglichen Situationen zu haben ist:

  1. Kein Fall immer geöffnet. Dies sollte 0 zurückgeben.
  2. Ein Fall wurde bereits geöffnet, ist aber jetzt geschlossen. Auch dies sollte 0 zurückgeben.
  3. Ein geöffneter Fall existiert. Dies sollte 1 zurückgeben.

Antwort

8

Ich denke, diese Abfrage wird tun, was Sie suchen; Beachten Sie, dass Ihre bestehende Abfrage einen Fehler hat, dass bei mehr als einem Fall nur überprüft wird, ob der zufällig ausgewählte Fall durch die erste Abfrage ausgewählt wurde (natürlich nur, wenn mehr als ein Fall möglich ist) einem bestimmten Standort zugewiesen).

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

In meinem Fall kann man nur 1 Fall zu einem Zeitpunkt geöffnet haben, um zu prüfen, ob das letzte Element eine Schließung ist, wird in diesem Fall ausreichen. Ich sollte dies in der Problembeschreibung notieren. –

+0

Entschuldigung - ich denke, ich hätte etwas konkreter sein sollen, als ich sagte "Überprüfen, ob der letzte Fall geschlossen ist" - Dies ist nicht unbedingt der neueste, die Reihenfolge wird nicht spezifisch sein, es sei denn, Sie fügen explizit eine ORDER BY-Klausel hinzu. –

+0

Ihr war derjenige, der gerade die Box funktionierte, also bekommen Sie die Zecke, auch wenn es nicht am leichtesten zu verstehen ist. –

4

Überprüfen Sie, ob dies für Sie funktioniert. Bearbeitet

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 bekomme einen Fehler 156: Falsche Syntax nahe dem Schlüsselwort 'BEGIN'.Inkorrekte Syntax in der Nähe des Schlüsselwortes' THEN '. –

+0

Überprüfen Sie noch einmal, ich korrigierte, IF-Syntax für CASE-Syntax geändert –

+0

Überprüfen Sie jedoch Edoodes Antwort, die auch sehr gut ist –

1

Dies könnte auch funktionieren:

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

Aus irgendeinem Grund schlägt dies in einem der beiden Fälle fehl, wenn Daten vorhanden sind. Fall 1 ist kein Fall jemals geöffnet - das funktioniert. Fall 2 ist Fall wurde zuvor geöffnet, ist aber jetzt geschlossen - dies schlägt fehl 1 zurück. Fall 3 ist, wo ein geöffneter Fall existiert - dies passiert zurück 1. –

+0

@ Graham. Mit einigen Beispieldaten könnte ich helfen – edosoft

1

Try this:

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

viele Möglichkeiten, dieses Problem zu lösen, ist hier ein:

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

Dies tut nicht, was ich brauchte. –

Verwandte Themen