2012-08-10 11 views
13

OK. Obtuve mucha ayuda here trabajando antes con un backend de SQL a un simple ... simplemente no para mí :(... solución de reloj de tiempo para la pequeña oficina en la que trabajo, ¡así que estoy de vuelta para más!Procedimiento almacenado SQL SI EXISTE ACTUALIZAR EL RESTO INSERT

Mi mesa Actualmente estoy trabajando con consta de 6 columnas:

  1. fecha clockDate no PK nula
  2. varchar nombre de usuario (50) no nula PK
  3. tiempo clockin (0)
  4. tiempo Breakout (0)
  5. breakIn time (0)
  6. tiempo Clockout (0)

aunque yo había descubierto mi declaración IF NOT EXISTS INSERT ELSE UPDATE de mi última pregunta, pero ahora estoy tratando de utilizarlo en un procedimiento almacenado, en lugar de una consulta sencilla ventana, sin éxito.

Básicamente un registro de usuario es una obviedad. Sin embargo, si el usuario no marca el reloj, pero salen a comer, la declaración debe crear la fila en lugar de actualizar una fila existente. La autorización así que aquí está mi procedimiento almacenado:

ALTER PROCEDURE dbo.BreakOut 
(
    @userName varchar(50) 
) 
AS 

IF EXISTS (SELECT * FROM Clock WHERE clockDate = GETDATE() AND userName = @userName) 
    BEGIN 
     UPDATE Clock SET breakOut = GETDATE() 
      WHERE clockDate = GETDATE() AND userName = @userName 
    END 
ELSE 
    BEGIN 
     INSERT INTO Clock (clockDate, userName, breakOut) 
      VALUES (GETDATE(), @userName, GETDATE()) 
    END 

Aquí es mi problema ... Si el usuario DID reloj en el día recibo una violación clave primaria debido a que el procedimiento almacenado todavía está tratando de ejecutar la parte INSERT de la declaración y nunca ejecuta la línea UPDATE. Lo intenté con un IF NOT EXISTS también con el mismo resultado. ¿Cuál es el truco para hacer que IF-ELSE funcione en un procedimiento almacenado? ¿Se puede hacer esto de la manera que estoy pensando o tengo que estudiar la declaración Merge? Mi plan es ejecutar los procedimientos almacenados desde un simple programa de Visual Basic en cada estación de trabajo. Tal vez me estoy poniendo en mi cabeza :(A malo mi jefe es demasiado barato para comprar una solución de reloj de tiempo

EDITAR:

gracias a todos por su ayuda !! estoy cayendo enamorada de este sitio, preguntas obtienen respuestas tan rápido !!! Aquí está mi procedimiento almacenado de trabajo:?

ALTER PROCEDURE dbo.BreakOut 
(
    @userName varchar(50) 
) 
AS 

IF EXISTS (SELECT * FROM Clock WHERE DateDiff(dd, GetDate(),clockDate) = 0 AND userName = @userName) 
    BEGIN 
     UPDATE Clock SET breakOut = GETDATE() 
      WHERE DateDiff(dd, GetDate(),clockDate) = 0 AND userName = @userName 
    END 
ELSE 
    BEGIN 
     INSERT INTO Clock (clockDate, userName, breakOut) 
      VALUES (GETDATE(), @userName, GETDATE()) 
    END 

¿es esta correcta, o se podría mejorar más Una vez más gracias a todos TANTO !!!

+1

es su instrucción IF - no suele existir un registro con el tiempo GETDATE() porque eso es ahora, ya que devuelve el tiempo, también! Lo que quiere hacer es ver si ya existe un registro para ese usuario en esa fecha. – dash

+1

Gracias @dash !! – tmhalbert

Respuesta

9

Este es probablemente el problema aquí: DONDE clockDate = GETDATE()

GetDate devuelve la fecha actual Y la hora actual, que no coincidiría con clockDate. Puede comparar las fechas con DifFecha lugar:

WHERE DateDiff(dd, GetDate(),clockDate) = 0 
+1

Me gustaría marcar esta la respuesta, pero no tengo la reputación, lo siento! ¡¡¡¡¡¡¡PERO GRACIAS!!!!!!! – tmhalbert

+0

¿Será esto un problema cuando llegue el día de hoy o no? ¿'Dd' se refiere a la parte del día de la cadena de fecha? – tmhalbert

+0

¿Puedo usar 'dy' en su lugar? – tmhalbert

3

Su problema parece ser la siguiente:

Imaginemos el usuario en el reloj en 09:00

Un registro como la siguiente podría existir:

 
ClockDate userName clockIn breakOut breakIn clockOut 
12/08/2012 joe   09:00  NULL  NULL  NULL 

Ahora su instrucción IF está haciendo esto:

SELECT * FROM Clock WHERE clockDate = "20120812 17:24:13" AND userName = @userName 

es decir, este registro no existirá.

En su lugar, intente esto:

IF EXISTS (SELECT * FROM Clock WHERE clockDate = DATEADD(D, 0, DATEDIFF(D, 0, GETDATE())) AND userName = @userName) 

También es necesario asegurarse de que está almacenando clockDate tan sólo la parte de fecha de GETDATE(), de lo contrario, tendría que ajustar su consulta, así:

IF EXISTS (SELECT * FROM Clock WHERE DATEADD(D, 0, DATEDIFF(D, 0, clockDate)) = DATEADD(D, 0, DATEDIFF(D, 0, GETDATE())) AND userName = @userName) 
+0

Me encanta como lo rompiste, ¡¡Gracias !! – tmhalbert

0
CREATE PROCEDURE `SP_GENRE_SELECT`(
    IN _Id INTEGER, 
     IN _Name VARCHAR(50), 
     IN _account VARCHAR (50), 
     IN _Password VARCHAR (50), 
     IN _LastConnexionDate DATETIME, 
     IN _CreatedDate DATETIME, 
     IN _UpdatedDate DATETIME, 
     IN _CreatedUserId INTEGER, 
     IN _UpdatedUserId INTEGER, 
     IN _Status TINYINT 
    ) 
BEGIN 
     SELECT * 
     FROM user 
     WHERE Id LIKE IF(_Id IS NULL,'%',CAST(_Id AS VARCHAR(50))) 
     AND 
     Name LIKE IF(_Name IS NULL,'%',CONCAT('%',_Name,'%')) 
     AND 
     Account LIKE IF(_Account IS NULL,'%',CONCAT('%',_Account,'%')) 
     AND 
     LastConnexionDate LIKE IF(_LastConnexionDate IS NULL,'%',CONCAT('%',CAST(LastConnexionDate AS VARCHAR(50),'%'))) 
     AND 
     CreatedDate LIKE IF(_CreatedDate IS NULL,'%',CONCAT('%',CAST(_CreatedDate AS VARCHAR(50),'%'))) 
     AND 
     UpdatedDate LIKE IF(_UpdatedDate IS NULL,'%',CONCAT('%',CAST(_UpdatedDate AS VARCHAR(50),'%'))) 
     AND 
     CreatedUserID LIKE IF(_CreatedUserID IS NULL,'%',CONCAT('%',CAST(_CreatedUserID AS VARCHAR(50),'%'))) 
     AND 
     UpdatedUserID LIKE IF(_UpdatedUserID IS NULL,'%',CONCAT('%',CAST(_UpdatedUserID AS VARCHAR(50),'%'))) 
     AND 
     Status LIKE IF(_Status IS NULL,'%',CAST(_Status AS VARCHAR(50),'%')) 

END 
Cuestiones relacionadas