我很抱歉,但这是一个分为两个部分的问题。
我是SQL的新手,正在尝试为我工作的小型办公室开发一个时钟应用程序。我现在正在使用SQL后端,并对复合语句有疑问。
我遇到的问题是,如果用户尝试暂停工作,但从未在轮班开始时进行操作,则SQL需要创建一个新行,而不是更新现有行。
这是我尝试过的:
IF NOT EXISTS(SELECT * FROM Clock WHERE clockDate = '08/10/2012') AND userName = 'test') BEGIN INSERT INTO Clock(clockDate, userName, breakOut) VALUES({ fn NOW() }, 'test', { fn NOW() }) END ELSE BEGIN UPDATE Clock SET breakOut = { fn NOW() } WHERE (clockDate = '08/10/2012') AND (userName = 'test') END
我正在使用Visual Studio 2010将其连接到本地计算机上的SQL Server Express 2008。我收到一条错误消息:“不支持Composite语句SQL构造或语句。” 但是,这之后会显示一条消息,指出1行已受影响,当我查看我的Clock表时,它看起来就像我期望的样子。做到这一点的最佳方法是什么?
我的第二部分问题在我的WHERE语句中。是否有一个函数可以在clockDate列中获取今天的日期,而不必填充今天的日期?只是尝试为构建前端应用程序考虑一下。
IF NOT EXISTS(SELECT * FROM Clock WHERE clockDate = { fn CURRENT_DATE() }) AND userName = 'test')
再次,这给了我想要的结果,但是直到出现错误“ CURRENT_DATE附近的WHERE子句中的错误。无法解析查询文本”之后,我才得到结果。
我希望我已经正确解释了这一点,并感谢您的帮助!
编辑:
@RThomas @ w00te
好的,因此使用clockDate作为日期字段,将breakOut作为time(0)字段,是否可以正常工作?原因我仍然收到“不支持Composite语句SQL构造或语句”。语法错误,即使它似乎正在工作。
IF NOT EXISTS (SELECT * FROM Clock WHERE (clockDate = GETDATE()) AND (userName = 'test')) BEGIN INSERT INTO Clock(clockDate, userName, breakOut) Values(GETDATE(), 'test', GETDATE()) END ELSE BEGIN UPDATE Clock SET breakOut = GETDATE() WHERE (clockDate = GETDATE()) AND (userName = 'test') END
我的表结果是:
clockDate userName clockIn breakOut breakIn clockOut
08/10/2012 test NULL 11:24:38 NULL NULL 这是我想要的结果,但是此错误使我感到困惑。这是Visual Studio错误还是SQL错误?我将阅读合并声明,谢谢你们的链接。
乍一看,您最初的尝试似乎非常接近。我假设ClockDate是一个DateTime字段,所以请尝试以下操作:
IF (NOT EXISTS(SELECT * FROM Clock WHERE cast(clockDate as date) = '08/10/2012') AND userName = 'test') BEGIN INSERT INTO Clock(clockDate, userName, breakOut) VALUES(GetDate(), 'test', GetDate()) END ELSE BEGIN UPDATE Clock SET breakOut = GetDate() WHERE Cast(clockDate AS Date) = '08/10/2012' AND userName = 'test' END
请注意,getdate为您提供当前日期。如果尝试与日期(无时间)进行比较,则需要强制转换,否则时间元素将导致比较失败。
如果clockDate不是日期时间字段(仅日期),则SQL引擎将为您执行此操作-无需强制转换为set / insert语句。
IF (NOT EXISTS(SELECT * FROM Clock WHERE clockDate = '08/10/2012') AND userName = 'test') BEGIN INSERT INTO Clock(clockDate, userName, breakOut) VALUES(GetDate(), 'test', GetDate()) END ELSE BEGIN UPDATE Clock SET breakOut = GetDate() WHERE clockDate = '08/10/2012' AND userName = 'test' END
正如其他人指出的那样,merge语句是解决此逻辑的另一种方法。但是,在某些情况下,尤其是对于大型数据集,merge语句可能会非常缓慢,从而导致大量的tran日志活动。因此,知道如何如上所示进行逻辑运算仍然是有效的技术。