복붙노트

[SQL] SQL 서버 2008 - IF는 NOT INSERT ELSE UPDATE 존재

SQL

SQL 서버 2008 - IF는 NOT INSERT ELSE UPDATE 존재

나는 죄송하지만이 두 부분 질문의 종류이다.

나는 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

나는 내 로컬 컴퓨터에 SQL Server Express에 2008에 연결이 작업을 수행하기 위해 비주얼 스튜디오 2010을 사용하고 있습니다. 나는 말한다 오류 수는 "복합 문 SQL 구문 또는 문이 지원되지 않습니다." 그러나, 1 개 행이 영향되었다는 메시지 다음에, 나는 내 시계 테이블을 볼 때 그것은 단지 내가 모습을 기대하는 것처럼 보인다. 이 acclompish하는 가장 좋은 방법은 무엇입니까?

그리고이 질문에 대한 나의 두 번째 부분은 내 WHERE 문입니다. clockDate 열에서 오늘 날짜를 얻기보다는 채우기 오늘 날짜로해야하는 기능이 있습니까? 그냥 프론트 엔드 응용 프로그램을 구축하기위한 앞서 생각하려고합니다.

    IF NOT EXISTS(SELECT * FROM Clock WHERE clockDate = { fn CURRENT_DATE() }) AND userName = 'test')

다시 말하지만, 이것은 나에게 내가 원하는 결과를 얻을 수 있지만까지 오류 점점 후 " 'CURRENT_DATE'근처. 수 없습니다 절은 쿼리 텍스트를 구문 분석하는 WHERE 오류를."

내가 제대로이 설명했다 바라며, 여러분의 도움에 감사드립니다!

편집하다:

@ RThomas @ o00te

좋아, 그럼 한 번 (0) 필드로 날짜 필드와 브레이크 아웃과 clockDate와,이 작업을해야합니까? 나는 여전히지고있어 원인는 "복합 문 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

이것은 내가 원하는 결과 만이 오류는 나를 혼란. 이 비주얼 스튜디오 오류 또는 SQL 오류인가? 내가 병합 문에 읽을 것, 링크에 대한 여러분 모두 감사합니다.

해결법

  1. ==============================

    1.언뜻 보면 원래의 시도는 아주 가까이 보인다. 나는 clockDate이 날짜 시간 필드 그래서 이것을 시도이라고 가정하고 있습니다 :

    언뜻 보면 원래의 시도는 아주 가까이 보인다. 나는 clockDate이 날짜 시간 필드 그래서 이것을 시도이라고 가정하고 있습니다 :

    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 엔진은 당신을 위해 그것을 할 것 - 세트 / 삽입 문에 캐스트 할 필요.

    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 
    

    다른 사람들이 지적 아웃이 때, 병합 문은 다음과 같은 논리를 해결하는 또 다른 방법입니다. 그러나 어떤 경우에는, 특히 대용량 데이터 세트로 병합 문은 트란 로그 작업의 많은 원인이 엄청나게 느릴 수 있습니다. 위 그림과 같이 논리 그것을 여전히 유효한 기술이다 방법을 아는 그래서.

  2. ==============================

    2.코드는 일부 (... 선택) 존재하지에 if 문에 오타가 있습니다. 내부 SELECT 문은 사용자 이름 조건이되지에서 제외되는 동안 상태가 잘못 중괄호 완료로 인해 존재 하나 있습니다. 어떤 경우에 당신은 동굴 너무 많은 닫는 중괄호.

    코드는 일부 (... 선택) 존재하지에 if 문에 오타가 있습니다. 내부 SELECT 문은 사용자 이름 조건이되지에서 제외되는 동안 상태가 잘못 중괄호 완료로 인해 존재 하나 있습니다. 어떤 경우에 당신은 동굴 너무 많은 닫는 중괄호.

    나는 두를 사용하고 있다는 사실에 따라이 가정 어디에 나중에 코드에서의 업데이트 문에서 조건.

    의 내 대답에 계속하자 ...

    MERGE 문은 아주 잘 "삽입 또는 업데이트"상황에 적합한 아름다운 TSQL 보석이다. 귀하의 경우는 다음 코드와 유사합니다. 나는 가능성이 프로 시저 매개 변수 (나는 생각한다)에 저장되어 어떤 변수를 선언하고있어 것을 고려.

    declare @clockDate date = '08/10/2012';
    declare @userName = 'test';
    
    merge Clock as target
    using (select @clockDate, @userName) as source (ClockDate, UserName)
    on (target.ClockDate = source.ClockDate and target.UserName = source.UserName)
    when matched then
        update
        set BreakOut = getdate()
    when not matched then
        insert (ClockDate, UserName, BreakOut)
        values (getdate(), source.UserName, getdate());
    
  3. ==============================

    3.

    IF NOT EXISTS(SELECT * FROM Clock
    WHERE clockDate = '08/10/2012') AND userName = 'test')
    

    추가 괄호를 가지고 있습니다. 당신이 그것을 제거하면 나는 그것의 벌금을 생각한다 :

    IF NOT EXISTS(SELECT * FROM Clock WHERE
    clockDate = '08/10/2012' AND userName = 'test')
    

    당신은 시간을 원하지 않는 경우에 당신이 조금 플레이해야하지만 또한, GETDATE ()는 열에서 현재 날짜를 넣어 것입니다. 나는 CONVERT (VARCHAR (8), GETDATE (), 112) 당신에게 단지 날짜 (시간이 아닌) 부분을 줄 것이라고 생각합니다.

    IF NOT EXISTS(SELECT * FROM Clock WHERE
    clockDate = CONVERT(varchar(8), GETDATE(), 112)
    AND userName = 'test')
    

    아마 그것을해야한다.

    PS : 병합 문을 사용합니다 :)

  4. ==============================

    4.당신은 WHERE clockDate = {FN CURRENT_DATE ()} 이름 및 사용자 이름 = '테스트'로 교체해야합니다. 에서 {FN CURRENT_DATE ()}) ")"추가 제거하십시오

    당신은 WHERE clockDate = {FN CURRENT_DATE ()} 이름 및 사용자 이름 = '테스트'로 교체해야합니다. 에서 {FN CURRENT_DATE ()}) ")"추가 제거하십시오

  5. from https://stackoverflow.com/questions/11906506/sql-server-2008-if-not-exists-insert-else-update by cc-by-sa and MIT license