데이터베이스 개발자 질문과 답변 게시판
1.번 프로시저 이 프로시저는 새벽 4시에 스케줄러를 통해 자동으로 실행됩니다.
ALTER procedure [dbo].[back_check_date]
As
set nocount on
set transaction isolation level read uncommitted
--변수선언
Begin Tran
--테이블 백업
INSERT INTO SHA_CHECK_BACK
SELECT * FROM SHA_check WITH(NOLOCK);
if @@error <> 0
begin
rollback tran
return
end
else
begin
--데이터 삭제
DELETE FROM SHA_CHECK;
-- 임시테이블 삭제
DELETE FROM sha_check_temp ;
end
commit tran
set nocount off
1번 프로시저 기능은 어제날짜의 데이터를 sha_check_back 테이블에 복해서 넣고
sha_check, sha_check_temp 데이터를 지워 주는 기능을 합니다.
2번프로시저 이프로시저는 새벽 4시30분에 자동 실행됩니다.
USE [nitTest2]
GO
/****** Object: StoredProcedure [dbo].[create_check_date] Script Date: 07/30/2013 09:24:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[create_check_date]
As
set nocount on
set transaction isolation level read uncommitted
--변수선언
declare @day varchar(10)
declare @day_inTime varchar(20)
declare @day_outTime varchar(20)
declare @sql Nvarchar(2000)
declare @sql2 Nvarchar(2000)
declare @sql3 Nvarchar(2000)
select @day = datename(dw,getdate())
if @day = '월요일'
begin
set @day_inTime = 'in_time_mon'
set @day_outTime = 'out_time_mon'
end
Else if @day = '화요일'
begin
set @day_inTime = 'in_time_tue'
set @day_outTime = 'out_time_tue'
end
Else if @day = '수요일'
begin
set @day_inTime = 'in_time_wed'
set @day_outTime = 'out_time_wed'
end
Else if @day = '목요일'
begin
set @day_inTime = 'in_time_thu'
set @day_outTime = 'out_time_thu'
end
Else if @day = '금요일'
begin
set @day_inTime = 'in_time_fri'
set @day_outTime = 'out_time_fri'
end
Else if @day = '토요일'
begin
set @day_inTime = 'in_time_sat'
set @day_outTime = 'out_time_sat'
end
Else if @day = '일요일'
begin
set @day_inTime = 'in_time_sun'
set @day_outTime = 'out_time_sun'
end
Begin Tran
set @sql = N' insert into SHA_check(UserID, AcaID, check_date,in_time, out_time , check_flag ) '
+ 'select a.UserID,a.AcaID,CONVERT(varchar(10), GETDATE(), 23)as check_date ,b.inTime, b.outTime , ''N'' '
+ ' from('
+ ' select id, UserID, AcaID from sha_student where people=''재원'' and flag=''Y'' '
+ ' )a '
+ ' inner join '
+ ' ( '
+ ' select * from ( select StuID, AcaID, '+@day_inTime+' as ''inTime'','+@day_outTime+' as ''outTime'', '
+ ' reg_date , rank()over(partition by stuid order by reg_date desc ) as ran from SHA_student_weektime )n '
+ ' where ran = 1 '
+ ' )b '
+ ' on a.ID = b.StuID '
+ ' where a.userid not in(select userid from sha_check c where check_date = convert(varchar(10),getdate(),23) and a.userid = c.userid and a.acaid = c.AcaID ) '
--execute sp_executesql @sql
--print @sql
exec (@sql)
if @@error <> 0
begin
rollback tran
return
end
Else
begin
commit tran
end
-- 임시테이블에 오늘 데이터 삽입
INSERT INTO SHA_CHECK_TEMP(userid, acaid, check_date, in_time, in_check, in_check_msg, out_time, out_check, out_check_msg, check_flag, check_flag_m, late_flag)
SELECT userid, acaid, check_date, in_time, in_check, in_check_msg, out_time, out_check, out_check_msg, check_flag, check_flag_m, late_flag FROM SHA_CHECK ;
set nocount off
이프로시저의 기능은 sha_check, sha_check_temp 테이블에 오늘 데이터를 생성하여 넣어주는 기능을 하는 프로시저 입니다.
1번, 2번 프로시저가 다 실행되고 난 후 이해가 안되는 부분이 있어서 이렇게 질문을 올립니다.
sha_check_back 테이블에는 절대 오늘 날짜의 데이터가 들어 올수 없습니다. 그러나 실행 결과를 보면 모든 데이터가 다 그런것은 아니고
일부 몇몇 오늘자 데이터가 sha_check_back 테이블에 들어 있더군요 이해 가 가질 않습니다. 분명 백업하는 프로시저는 새벽4시에 실행
이되고 오늘 데이터를 만들어 주는 프로시저는 새벽 4시30분에 실행이 되는데 어떡게 sha_check_back 에 오늘 데이터가 들어가 있는지 이
해가 안되 는군요 ㅜ 쿼리문 순서나 로직은 제가 봐도 이상이 없는 듯 합니다. 왜냐하면 테스트 서버에서는 아무이상이 없었거든요 ..
그래서 의심이 가는게 실서버는 접속하는 사람들이 많아서
1번 프로시저에
--테이블 백업
INSERT INTO SHA_CHECK_BACK
SELECT * FROM SHA_check WITH(NOLOCK);
이작업 도중에 락이 걸리는 걸까요?? ㅜ 참고로 sha_check 테이블에는 업데이트가 빈번히 이루어 집니다. .(하지만 새벽시간에는 거의 없음)
웹개발자라.. 디비에 지식이 부족하여 이렇게 문의 드립니다 ㅜ
데이터를 옮길때 주의 해야 할 점이나 락을 피하는 방법 같은것 도 있으면 조언좀 부탁 드릴께요
감사합니다 ^^
Comment 3
-
catchv
2013.07.30 11:41
-
건우아빠
2013.07.30 14:27
1번과2번 프로시저를 합해서 하시는 방향으로 하세요..
SHA_CHECK_BACK테이블에도 처리된 시간을 default로 설정을 해보세요..
실질적으로 처리된 시간이 언제냐를 보셔야 할듯 합니다...
-
처리짱
2013.07.30 14:30
INSERT INTO SHA_CHECK_BACK
SELECT * FROM SHA_check WITH(NOLOCK); ->SELECT * INTO SHA_CHECK_BACK
FROM SHA_check WITH(NOLOCK) 식으로 테이블이 존재하는지 체크하는 부분이 있어야겠죠? 임시테이블로 하는거소 괜찬을듯..DELETE FROM SHA_CHECK -> TRUNCATE TABLE SHA_CHECK 로 하시는것도 도움이 될듯 하네요
솔직히 잘은 모르겠지만 생각나는대로 적어 보면
INSERT INTO SHA_CHECK_BACK
SELECT * FROM SHA_check WITH(NOLOCK); -- 이거 전에 정말 오늘 데이터가 없는지는 먼저 확인해 보시고
JOB이 중복 된다고 생각하시면 시간 으로 하지 마시고 JOB에 4시 JOB을 1단계로 4:30분 JOB을 1단계 완료후 실행되는 2단계로
넣으시면 될 것 같고요.
INSERT INTO SHA_CHECK_BACK
SELECT * FROM SHA_check WITH(NOLOCK)
WHERE DATETIME(???) < CONVERT(VARCHAR(8), GETDATE(), 112)
로 해서 정확하게 오늘 이전 데이터 만 넣어주는 구조로 변경하는 것이 어떨까요?