SQL Server 2008-존재하지 않는 경우 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
Visual Studio 2010을 사용하여 로컬 컴퓨터의 SQL Server Express 2008에 연결하여이 작업을 수행하고 있습니다. "The Compound statement SQL Construct or statement is not supported."라는 오류가 표시됩니다. 그러나 그 다음에는 1 개의 행이 영향을 받았다는 메시지가 나옵니다. 시계 테이블을 보면 예상했던 것과 똑같습니다. 이것을 촉진하는 가장 좋은 방법은 무엇입니까?
이 질문의 두 번째 부분은 내 WHERE 문에 있습니다. 오늘 날짜를 채우지 않고 clockDate 열에서 오늘 날짜를 가져 오는 함수가 있습니까? 프런트 엔드 애플리케이션을 구축하기 위해 미리 생각하려고합니다.
IF NOT EXISTS(SELECT * FROM Clock WHERE clockDate = { fn CURRENT_DATE() }) AND userName = 'test')
다시 말하지만 " 'CURRENT_DATE'근처의 WHERE 절에 오류가 있습니다. 쿼리 텍스트를 구문 분석 할 수 없습니다."라는 오류가 발생하기 전까지는 원하는 결과를 얻을 수 없습니다.
잘 설명해 주셨으면 좋겠습니다. 도와 주셔서 감사합니다 !!
편집하다:
트윗 담아 가기
좋습니다. clockDate를 날짜 필드로, breakOut을 time (0) 필드로 사용하면 작동합니까? 원인 여전히 "The Compound statement SQL Construct or statement is not supported."라는 메시지가 나타납니다. 작동하는 것처럼 보이지만 구문 오류입니다.
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 오류입니까? 그리고 나는 Merge Statements를 읽을 것입니다. 링크에 대해 감사드립니다.
언뜻보기에 당신의 원래 시도는 꽤 비슷해 보입니다. 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가 datetime 필드가 아니라면 (날짜 만) 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 로그 활동을 유발할 수 있습니다. 따라서 위와 같이 논리를 어떻게 처리하는지 아는 것은 여전히 유효한 기술입니다.
다른 사람들이 MERGE 문을 조사해야한다고 제안했지만 아무도이를 사용하여 솔루션을 제공하지 않았으므로이 특정 TSQL 구문에 대한 내 답변을 추가하고 있습니다. 나는 당신이 그것을 좋아할 것이라고 장담합니다.
중요 사항
Your code has a typo in your if statement in not exists(select...) part. Inner select statement has only one where condition while UserName condition is excluded from the not exists due to invalid brace completion. In any case you cave too many closing braces.
I assume this based on the fact that you're using two where conditions in update statement later on in your code.
Let's continue to my answer...
SQL Server 2008+ support MERGE statement
MERGE statement is a beautiful TSQL gem very well suited for "insert or update" situations. In your case it would look similar to the following code. Take into consideration that I'm declaring variables what are likely stored procedure parameters (I suspect).
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());
IF NOT EXISTS(SELECT * FROM Clock
WHERE clockDate = '08/10/2012') AND userName = 'test')
Has an extra parenthesis. I think it's fine if you remove it:
IF NOT EXISTS(SELECT * FROM Clock WHERE
clockDate = '08/10/2012' AND userName = 'test')
Also, GETDATE() will put the current date in the column, though if you don't want the time you'll have to play a little. I think CONVERT(varchar(8), GETDATE(), 112) would give you just the date (not time) portion.
IF NOT EXISTS(SELECT * FROM Clock WHERE
clockDate = CONVERT(varchar(8), GETDATE(), 112)
AND userName = 'test')
should probably do it.
PS: use a merge statement :)
You need to replace it as WHERE clockDate = { fn CURRENT_DATE() } AND userName = 'test'. Please remove extra ")" from { fn CURRENT_DATE() })
참고URL : https://stackoverflow.com/questions/11906506/sql-server-2008-if-not-exists-insert-else-update
'program story' 카테고리의 다른 글
| 데코레이터에서 자신에 액세스 (0) | 2020.11.15 |
|---|---|
| 더 큰 스레드 풀을 사용하는 대신 비동기 요청을 사용하는 이유는 무엇입니까? (0) | 2020.11.15 |
| typescript와 함께 스프레드 구문 및 new Set () 사용 (0) | 2020.11.14 |
| 객체 분해의 유형 (0) | 2020.11.14 |
| 규칙 엔진-장단점 (0) | 2020.11.14 |