2009-07-24 11 views
29

Ok, so ist mein Schema folgt aus:SQL Server IF EXISTS Verwendung?

Tabelle: Timesheet_Hours

Spalten:

  • Timesheet_Id (PK, int)
  • Staff_Id (int)
  • BookedHours (int)
  • Posted_Flag (boolean)

Dies ist eine extrem vereinfachte Version der Tabelle, aber sie wird für die Zwecke dieser Erklärung dienen. Angenommen, eine Person kann immer nur einen Zeiterfassungssatz haben.

Was ich versuche, ist Datensätze in eine andere Tabelle, genannt WorkLog hinzufügen. Jedem Datensatz ist eine Zeit zugeordnet. Wenn diese Tabelle aktualisiert wird, möchte ich auch Timesheet_Hours aktualisieren.

Bevor ich Timesheet_Hours aktualisiere, möchte ich zuerst überprüfen, dass die relevanten Arbeitszeittabellen nicht bereits gebucht wurden, und dann möchte ich überprüfen, ob tatsächlich ein Datensatz zu aktualisieren ist.

Der erste Teil der if-Anweisung, der prüft, ob die Arbeitszeittabellen nicht bereits gebucht wurden, funktioniert einwandfrei. Das Problem ist der zweite Teil. Es wird überprüft, ob der zu aktualisierende Datensatz bereits existiert. Das Problem ist, dass es immer einen Fehler auslöst.

Hinweis: Der folgende Code wird aus einer gespeicherten Prozedur extrahiert, die von dem Update ausgeführt wird, Trigger in der WorkLog-Tabelle einfügen und löschen. @PersonID ist einer der Parameter für diese Tabelle. Die gespeicherte Prozedur funktioniert einwandfrei, wenn ich den zweiten Teil dieser Anweisung auskommentiere.

IF EXISTS 
    (
    SELECT 1 
    FROM Timesheet_Hours 
    WHERE Posted_Flag = 1 
    AND Staff_Id = @PersonID 
    ) 

    BEGIN 
     RAISERROR('Timesheets have already been posted!', 16, 1) 
     ROLLBACK TRAN 
    END 
ELSE 
    IF NOT EXISTS 
     (
     SELECT 1 
     FROM Timesheet_Hours 
     WHERE Staff_Id = @PersonID 
     ) 

     BEGIN 
      RAISERROR('Default list has not been loaded!', 16, 1) 
      ROLLBACK TRAN 
     END 
+0

Ist 1 der Name einer Spalte in Ihrer Tabelle "Timesheet_Hours"? – SirDemon

+1

Nein, ist es nicht. Da ich EXISTS benutze, habe ich nur das verfolgt, was ich bei Sub-Queries mit EXISTS als Standard annahm. –

+2

1 in diesem Fall ist nur eine Konstante. Alles, was er interessiert, ist, dass eine Zeile zurückgegeben wird, nicht der Wert irgendwelcher Spalten. Die Verwendung einer Konstanten ist normalerweise schneller als die Verwendung von * oder einer bestimmten Spaltenliste. – Rick

Antwort

32

Haben Sie verifiziert, dass es tatsächlich eine Zeile gibt, in der Staff_Id = @PersonID? Was Sie gepostet haben, funktioniert in einem Testskript gut, vorausgesetzt, die Zeile existiert. Wenn Sie die INSERT-Anweisung auskommentieren, wird der Fehler ausgelöst.

set nocount on 

create table Timesheet_Hours (Staff_Id int, BookedHours int, Posted_Flag bit) 

insert into Timesheet_Hours (Staff_Id, BookedHours, Posted_Flag) values (1, 5.5, 0) 

declare @PersonID int 
set @PersonID = 1 

IF EXISTS  
    (
    SELECT 1  
    FROM Timesheet_Hours  
    WHERE Posted_Flag = 1  
     AND Staff_Id = @PersonID  
    )  
    BEGIN 
     RAISERROR('Timesheets have already been posted!', 16, 1) 
     ROLLBACK TRAN 
    END 
ELSE 
    IF NOT EXISTS 
     (
     SELECT 1 
     FROM Timesheet_Hours 
     WHERE Staff_Id = @PersonID 
     ) 
     BEGIN 
      RAISERROR('Default list has not been loaded!', 16, 1) 
      ROLLBACK TRAN 
     END 
    ELSE 
     print 'No problems here' 

drop table Timesheet_Hours 
+0

Danke Kumpel. Es stellte sich heraus, dass ich nicht die korrekte PersonID vom INSERT-Trigger übergeben habe. Es verwirrte mich, weil es mit den Auslösern UPDATE und DELETE funktionierte, aber ich dachte nicht daran, die Parameter zu überprüfen. –