2012-08-10 125 views
13

OK。我得到了很多幫助here早些時候與SQL後端工作到一個簡單的...只是不適合我:(...我工作的小型辦公室的時鐘解決方案,所以我回來了更多!SQL存儲過程IF EXISTS UPDATE ELSE INSERT

我的表,我目前正與包括6列:

  1. clockDate日期不爲空PK
  2. userName的VARCHAR(50)NOT NULL PK
  3. clockIn時間(0)
  4. 突破時間( 0)
  5. breakIn time (0)
  6. CLOCKOUT時間(0)

不過,我覺得我已經從我的最後一個問題想通了,我IF NOT EXISTS INSERT ELSE UPDATE聲明,但現在我想用它在存儲過程,而不是一個簡單的查詢窗口,沒有成功。

基本上用戶計時是一個不費腦筋。但是,如果用戶沒有進入時鐘,但他們午飯時間外出,則該語句需要創建該行而不是更新現有行。好了,所以這裏是我的存儲過程:

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 

這裏是我的問題......如果用戶在這一天,我收到了主鍵衝突,因爲該存儲過程仍在試圖運行該語句的INSERT部分DID時鐘並且從不運行UPDATE行。我試過它翻轉IF NOT EXISTS以及相同的結果。獲得IF-ELSE在存儲過程中工作的訣竅是什麼?可以這樣做他們的方式我在想什麼或我必須研究Merge聲明?我的計劃是在每個工作站上從簡單的Visual Basic程序運行存儲過程。也許我得到在我頭上:(壞我的老闆是太便宜到只買一個時鐘解決方案

編輯:

感謝大家的幫助!我愛你愛上了這個網站,問題得到答案這麼快!這是我工作的存儲過程:

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 

這是正確的,或可能是進一步提高再次感謝大家這麼多!

+1

這是你的IF語句 - 不會有存在的記錄與時間GETDATE(),因爲這是現在,當它返回的時候,太!您想要做的是查看該日期是否存在該用戶的記錄。 – dash 2012-08-10 23:04:27

+1

謝謝你@dash! – tmhalbert 2012-08-10 23:12:43

回答

9

這可能是這裏的問題:WHERE clockDate = GETDATE()

GetDate返回當前日期和當前時間,這與clockDate不匹配。你可以用DateDiff的,而不是比較的日期:

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

我會標記這個答案,但我沒有名譽,對不起!但謝謝你!!!!!!! – tmhalbert 2012-08-10 23:12:03

+0

當我到下個月的這一天,這會成爲一個問題,或者不是? 'dd'是指日期字符串的日期部分嗎? – tmhalbert 2012-08-10 23:33:03

+0

我可以用'dy'代替嗎? – tmhalbert 2012-08-10 23:38:55

3

您的問題似乎是以下幾點:

讓我們想象一下用戶在09:00

主頻在下面這樣的記錄可能存在:

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

現在您的IF聲明是這樣做的:

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

即該記錄不存在。

相反,試試這個:

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

您還需要確保你存儲clockDate剛剛GETDATE()的日期部分,否則,你就需要調整您的查詢像這樣:

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

愛你打倒那種方式,謝謝! – tmhalbert 2012-08-10 23:14:38

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