2012-08-10 14 views
13

OK. Dużo mi pomógł here wcześniej pracowałem z backendem SQL na prostą ... po prostu nie dla mnie :(... rozwiązanie zegara czasu dla małego biura, w którym pracuję, więc wracam po więcej!Procedura składowana SQL JEŚLI WSTECZ AKTUALIZACJĘ WSTAW ELSE WSTAW

Moja tabela obecnie pracuję z składa się z 6 kolumn:

  1. data clockDate not null PK
  2. nazwa_użytkownika varchar (50) NOT NULL PK
  3. czas clockIn (0)
  4. łamiąca czasowych (0)
  5. przerwa w czasie (0)
  6. czas clockOut (0)

I chociaż ja zorientowali się mój IF NOT EXISTS INSERT ELSE UPDATE oświadczenie od mojego ostatniego pytania, ale teraz staram się go używać w procedury przechowywanej, zamiast zwykłego zapytania okno, bez powodzenia.

Zasadniczo użytkownik wkraczający w to nie myślenia. Jeśli jednak użytkownik nie wkracza do zegara, ale zegar zostanie wyłączony na czas lunchu, instrukcja musi utworzyć wiersz zamiast aktualizować istniejący wiersz. Ok, więc tutaj jest mój procedura przechowywana:

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 

Oto mój problem ... Jeśli użytkownik DID zegar na dzień dostaję klucz podstawowy naruszenie ponieważ procedura przechowywana jest wciąż próbuje uruchomić INSERT część rachunku i nigdy nie uruchamia linii UPDATE. Próbowałem go obrócić z IF NOT EXISTS, a także z tym samym wynikiem. Jaka jest sztuczka, aby IF-ELSE działało w procedurze przechowywanej? Czy można to zrobić w taki sposób, w jaki myślę lub czy muszę studiować oświadczenie Merge? Moim planem jest uruchomienie procedur przechowywanych z prostego programu Visual Basic na każdej stacji roboczej. Może Dostaję ponad moją głową :(złej moim szefem jest zbyt tanie, aby tylko kupić rozwiązanie zegar czasu

EDIT:

Dziękuję wszystkim za pomoc !! spadam zakochany w tym miejscu, pytania uzyskać odpowiedzi tak szybko !!! Oto moja praca procedura przechowywana:

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 

Czy to właściwe, czy może to być poprawiona więcej Ponownie dziękuję wszystkim SO MUCH !!!

+1

to wyciągu IF - tam przyzwyczajenie istnieje zapis z getDate time() bo to teraz, ponieważ zwraca czas, też! To, co chcesz zrobić, to sprawdzić, czy istnieje rekord już dla tego użytkownika w tym dniu. – dash

+1

Dziękuję @dash !! – tmhalbert

Odpowiedz

9

Jest to prawdopodobnie problem tutaj: WHERE clockDate = GETDATE()

GetDate zwraca bieżącą datę ORAZ aktualną godzinę, która nie pasuje do clockDate. Można porównać daty z DateDiff Zamiast:

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

Oznaczę to jako odpowiedź, ale nie mam reputacji, przepraszam! ALE DZIĘKUJĘ!!!!!!! – tmhalbert

+0

Czy to będzie problem, gdy dotrę do tego dnia w przyszłym miesiącu, czy nie? Czy "dd" odnosi się do części dnia łańcucha daty? – tmhalbert

+0

Czy mogę zamiast tego użyć "dy"? – tmhalbert

3

Twój problem wydaje się być następujące:

Wyobraźmy użytkownik taktowany się o godzinie 09:00

rekord jak na poniższej ilustracji może istnieć:

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

Teraz twoje instrukcje IF robią to:

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

, tj. Ta płyta nie istnieje.

Zamiast tego, spróbuj tego:

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

Należy również upewnić się, że przechowywanie clockDate jak tylko data część GetDate(), w przeciwnym razie trzeba by dostosować zapytanie tak:

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

Uwielbiam sposób, w jaki to złamałeś, dziękuję !! – 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 
Powiązane problemy