2012-08-10 14 views
13

OK. Ho ricevuto molto aiuto here in precedenza con un backend SQL per un semplice ... non solo per me :(... soluzione di orologio per il piccolo ufficio in cui lavoro, quindi sono tornato per di più!SQL stored procedure SE EXISTS UPDATE ELSE INSERT

Il mio tavolo sto attualmente lavorando con composta da 6 colonne:

  1. data clockDate non nullo PK
  2. userName varchar (50) NOT NULL PK
  3. tempo clockin (0)
  4. tempo breakout (0)
  5. tempo di interruzione (0)
  6. tempo ClockOut (0)

io se avevo capito il mio IF NOT EXISTS INSERT ELSE UPDATE dichiarazione dalla mia ultima domanda, ma ora sto cercando di usarlo in una stored procedure, piuttosto che una query semplice finestra, senza successo.

Fondamentalmente un utente che esegue il clocking è un gioco da ragazzi. Tuttavia, se l'utente non effettua il clock, ma si fermano a pranzo, l'istruzione deve creare la riga anziché aggiornare una riga esistente. Ok, quindi ecco la mia stored procedure:

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 

Ecco il mio problema ... Se l'utente DID orologio per il giorno ricevo una violazione di chiave primaria perché la stored procedure sta ancora cercando di eseguire la parte INSERT della dichiarazione e non esegue mai la linea UPDATE. L'ho provato capovolto con uno IF NOT EXISTS con lo stesso risultato. Qual è il trucco per far funzionare IF-ELSE in una stored procedure? Questo può essere fatto nel modo in cui sto pensando o devo studiare la dichiarazione Merge? Il mio piano è di eseguire le stored procedure da un semplice programma Visual Basic su ogni workstation. Forse sto ricevendo in sopra la mia testa :(Per male il mio capo è troppo a buon mercato per comprare solo una soluzione orologio in tempo

EDIT:

Grazie a tutti per il vostro aiuto !! sto cadendo innamorato di questo sito, le domande ottenere risposte così veloce !!! Ecco il mio lavoro stored procedure:?

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 

è questo corretto, o potrebbe essere migliorato di più ancora una volta grazie a tutti così tanto !!!

+1

E 'il tuo istruzione IF - esistono solito un record con il tempo di GETDATE() perché questo è ora, in quanto restituisce il tempo, troppo! Quello che vuoi fare è vedere se esiste già un record per quell'utente in quella data. – dash

+1

Grazie @dash !! – tmhalbert

risposta

9

Questo è probabilmente il problema proprio qui: DOVE clockDate = GETDATE()

GetDate restituisce la data corrente AND l'ora corrente, che non corrisponde a clockDate. È possibile confrontare le date con DateDiff invece:

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

Vorrei segnare questa risposta ma non ho la reputazione, mi dispiace! MA GRAZIE!!!!!!! – tmhalbert

+0

Questo sarà un problema quando arriverò a questo giorno il prossimo mese, o no? 'Dd' si riferisce alla parte del giorno della stringa della data? – tmhalbert

+0

Posso usare 'dy' invece? – tmhalbert

3

Il tuo problema sembra essere il seguente:

Immaginiamo che l'utente clock in alle 09:00

Un record come il seguente potrebbe esistere:

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

Ora la tua istruzione IF sta facendo questo:

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

cioè questo record non esiste.

Invece, provate questo:

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

È inoltre necessario assicurarsi che si sta archiviando clockDate come solo la parte data di GETDATE(), in caso contrario, si avrebbe bisogno di modificare la query in questo modo:

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

Ama il modo in cui l'hai rotto, grazie !! – 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 
Problemi correlati