Подтвердить что ты не робот

SQL хранимая процедура IF EXISTS UPDATE ELSE INSERT

OK. Я получил большую помощь здесь ранее, работая с SQL-сервером до простого... просто не для меня:(... время для решения малого офиса я работайте, поэтому я вернусь больше!

Моя таблица, в которой я сейчас работаю, состоит из 6 столбцов:

  • clockDate date not null PK
  • userName varchar (50) не null PK
  • clockIn время (0)
  • breakOut time (0)
  • breakIn time (0)
  • clockOut time (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

Вот моя проблема... Если пользователь DID работает в течение дня, я получаю нарушение первичного ключа, потому что хранимая процедура все еще пытается запустить часть INSERT инструкции и никогда не запускает строку UPDATE. Я попробовал, чтобы он перевернулся с помощью IF NOT EXISTS, с тем же результатом. Какая уловка, чтобы заставить IF-ELSE работать в хранимой процедуре? Можно ли это сделать так, как я думаю, или мне нужно изучить инструкцию Merge? Мой план состоит в том, чтобы запускать хранимые процедуры из простой программы Visual Basic на каждой рабочей станции. Может быть, я нахожусь над моей головой: (К сожалению, мой босс слишком дешев, чтобы просто купить решение для часов!

EDIT:

Спасибо вам за помощь! Я влюбляюсь в этот сайт, вопросы получают ответы ТАК БЫСТРО!!! Вот моя работающая хранимая процедура:

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

Это правильно, или его можно улучшить? Снова благодарим вас ВСЕ СКОЛЬКО!!!

4b9b3361

Ответ 1

Это, вероятно, проблема прямо здесь: WHERE clockDate = GETDATE()

GetDate возвращает текущую дату И текущее время, которое не совпадает с clockDate. Вы можете сравнить даты с DateDiff вместо:

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

Ответ 2

Ваша проблема будет выглядеть следующим образом:

Представьте, что пользователь зашел в 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)

Ответ 4

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