2009-07-24 17 views
29

Ok, así que mi esquema es el siguiente:SQL Server SI NO EXISTE ¿Uso?

Tabla: Timesheet_Hours

Columnas:

  • Timesheet_Id (PK, int)
  • staff_id (int)
  • BookedHours (int)
  • Publicada_flag (booleana)

Esta es una versión extremadamente simplificada de la tabla, pero servirá para los propósitos de esta explicación. Suponga que una persona solo puede tener un registro de planilla de horas.

Lo que intento hacer es agregar registros a otra tabla, llamada WorkLog. Cada registro aquí tiene un tiempo asociado a él. Cuando se actualice esa tabla, también quiero actualizar Timesheet_Hours.

Antes de actualizar Timesheet_Hours, quiero verificar primero que las hojas de horas relevantes no hayan sido publicadas, y luego quiero verificar si hay un registro para actualizar en primer lugar.

La primera parte de la declaración if, que verifica que las hojas de tiempo no hayan sido publicadas, funciona bien. El problema es la segunda parte. No está claro si el registro que va a actualizar ya existe. El problema es que siempre genera un error.

NB: El siguiente código se extrae de un procedimiento almacenado ejecutado por la actualización, inserta y elimina desencadenantes en la tabla WorkLog. @PersonID es uno de los parámetros de esa tabla. El procedimiento almacenado funciona bien si comento la segunda parte de esta declaración.

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

¿Es 1 el nombre de una columna en su tabla Timesheet_Hours? – SirDemon

+1

No, no lo es. Como uso EXISTS, solo estaba siguiendo lo que pensé que era una práctica estándar en subconsultas usando EXISTS. –

+2

1 en ese caso es solo una constante. Lo único que le importa es que se devuelva una fila, no el valor de ninguna columna. Usar una constante suele ser más rápido que usar * o una lista de columnas específica. – Rick

Respuesta

32

¿Ha verificado que hay de hecho una fila donde Staff_ID = @PersonID? Lo que has publicado funciona bien en un script de prueba, suponiendo que exista. Si comenta la declaración de inserción, se genera el error.

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

Gracias amigo. Resultó que no estaba pasando el ID de persona correcto desde el disparador INSERTAR. Me estaba confundiendo porque estaba trabajando con los disparadores ACTUALIZAR y ELIMINAR, pero no pensé en verificar los parámetros. –

Cuestiones relacionadas