2012-08-10 123 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